nodejs裁剪图片

野生程序猿-杂烧4年前图像处理535

这是个真实的案例,下面脚本是真实跑通的,走过了一些坑,这里来给大家分享一下


首先描述一下场景,我们是做教学软件的,这个是开发一个X光机安检教学场景,有一些教学素材需要到学校指定服务器上截图过来,然后根据截图在裁成我们自己软件需要的尺寸。



有下面几个坑

1、截取的图片有当时太大截取不完整的,直接挑出来不用处理。

这个是先找到图像的中心点,然后在向外寻找,某些点的颜色不对就说明图片没有截取正确。


2、截取的图片需要裁成640*480像素的图片,比缩放适配这个尺寸

这个是先找到图像的中心点,然后在向外寻找,这样能计算出图片的尺寸,然后自己在算法调整。


3、需要操作中文目录下的文件

直接使用中文的报错,于是野生办法,把文件复制到一个非中文临时位置进行处理。


代码如下,有些乱,有需要的,可以参考一下

const { createCanvas, loadImage } = require('canvas')
var fs = require("fs");
var path = require("path");
var iconv = require('iconv-lite');

 var fun = require('./fun');
 
 
var argv = process.argv;
var $key=argv[2];
console.log($key);


function togbk(picurl)
{
	
	//picurl=iconv.decode(iconv.encode(picurl,'utf8'), 'gbk');
	var new_picurl='./temp/'+fun.randtime()+'.png';
	fs.copyFileSync(picurl,new_picurl);
	return new_picurl;
}

async function main(picurl,back){
	
	console.log(picurl);
	picurl=togbk(picurl);
	console.log(picurl);
	console.log('ssssssss11111');
	const myimg = await loadImage(picurl);
	console.log('sssssss2222s');
	const canvas = createCanvas(myimg.width, myimg.height)
	const ctx = canvas.getContext('2d');

	
	ctx.drawImage(myimg,0,0);
	let imgData = ctx.getImageData(0,0,myimg.width, myimg.height);
	let data = imgData.data;
	
	
	//计算高度
	var x1=0;
	var x2=0;
	var y1=0;
	var y2=0;
	for(var i=66;i<=830;i++)
	{
		var this_check = ctx.getImageData(654, i, 1, 1).data;
		//console.log(i,this_check);
		if(this_check[0]==0 && this_check[1]==0 && this_check[2]==0 && this_check[3]==255 )
		{
			y1=i;
			break;
		}
	}
	for(var i=830;i>=66;i--)
	{
		var this_check = ctx.getImageData(654, i, 1, 1).data;
		//console.log(i,this_check);
		if(this_check[0]==0 && this_check[1]==0 && this_check[2]==0 && this_check[3]==255 )
		{
			y2=i;
			break;
		}
	}	
	
	for(var i=60;i<=1340;i++)
	{
		var this_check = ctx.getImageData(i, 470, 1, 1).data;
		//console.log(i,this_check);
		if(this_check[0]==0 && this_check[1]==0 && this_check[2]==0 && this_check[3]==255 )
		{
			x1=i;
			break;
		}
	}
	for(var i=1340;i>=60;i--)
	{
		var this_check = ctx.getImageData(i, 470, 1, 1).data;
		//console.log(i,this_check);
		if(this_check[0]==0 && this_check[1]==0 && this_check[2]==0 && this_check[3]==255 )
		{
			x2=i;
			break;
		}
	}	

	console.log(x1,x2,y1,y2);
	
	var bili=(y2-y1)/480;
	var x3=(x2-x1)/2+x1;
	var y3=(y2-y1)/2+y1;
	
	const canvas2 = createCanvas(640, 480)
	const ctx2 = canvas2.getContext('2d');
	
	if(bili>1)
	{
		var x1=x3-320*bili;
		var x2=x3+320*bili;
		

		//ctx2.drawImage(canvas,x1,y1,640*bili,480*bili,0,0,640,480);	
	}else{
		var x1=x3-320;
		var x2=x3+320;
		var y1=y3-240;
		var y2=y3+240;
		
	
		//ctx2.drawImage(canvas,x1,y1,640,480,0,0,640,480);	
	}
	fs.unlinkSync(picurl);
	back({x1:x1,x2:x2,y1:y1,y2:y2});
	//canvas2.createPNGStream().pipe(fs.createWriteStream(tourl));
	
	
	//ctx.putImageData(imgData,0,0);

	 
}
 


async function savepic(obj,picurl,tourl){
	
	picurl=togbk(picurl);

	const myimg = await loadImage(picurl);
	const canvas = createCanvas(myimg.width, myimg.height)
	const ctx = canvas.getContext('2d');

	
	ctx.drawImage(myimg,0,0);
	let imgData = ctx.getImageData(0,0,myimg.width, myimg.height);
	
	
	let data = imgData.data;
	for(let i = 0; i < data.length; i++){
		/*
		var avg=(data[i]+data[i+1]+data[i+2])/3;
		//var avg = data[i]* 0.3 + data[i+1]* 0.59 + data[i+2]* 0.11
		data[i] = avg;
		data[i+1] = avg;
		data[i+2] = avg;
		*/

		var r = data[i];
		var g = data[i + 1];
		var b = data[i + 2];
		//这里可以对 r g b 进行计算(这里的rgb是每个像素块的rgb颜色)
		if(r==240 && g==240 && b==240)
		{
				imgData.data[i] = 255;
				imgData.data[i + 1] = 255;
				imgData.data[i + 2] = 255;	
			
		}
	
	
	}
		ctx.putImageData(imgData,0,0);	
	
	//计算高度
	var x1=obj.x1;
	var x2=obj.x2;
	var y1=obj.y1;
	var y2=obj.y2;
	
	
	var bili=(y2-y1)/480;
	var x3=(x2-x1)/2+x1;
	var y3=(y2-y1)/2+y1;
	
	const canvas2 = createCanvas(640, 480)
	const ctx2 = canvas2.getContext('2d');
	
	if(bili>1)
	{
		var x1=x3-320*bili;
		var x2=x3+320*bili;
		

		ctx2.drawImage(canvas,x1,y1,640*bili,480*bili,0,0,640,480);	
	}else{
		var x1=x3-320;
		var x2=x3+320;
		var y1=y3-240;
		var y2=y3+240;
		
	
		ctx2.drawImage(canvas,x1,y1,640,480,0,0,640,480);	
	}

	
	canvas2.createPNGStream().pipe(fs.createWriteStream(tourl));
	fs.unlinkSync(picurl);
	
	//ctx.putImageData(imgData,0,0);

	 
}
 



async function huidu_savepic(picurl,tourl){
	
	picurl=togbk(picurl);

	const myimg = await loadImage(picurl);
	const canvas = createCanvas(myimg.width, myimg.height)
	const ctx = canvas.getContext('2d');

	
	ctx.drawImage(myimg,0,0);
	let imgData = ctx.getImageData(0,0,myimg.width, myimg.height);
	
	
	let pixeldata = imgData.data;
	

	for(var i=0,len = pixeldata.length ;i<len;i+=4){ 
	var gray = Math.floor(( imgData.data[i] + imgData.data[i+1] + imgData.data[i+2])/3);//平均值灰度算法 
		imgData.data[i] = gray; 
		imgData.data[i+1] = gray; 
		imgData.data[i+2] = gray; 
	}

	ctx.putImageData(imgData,0,0);	


	ctx.drawImage(canvas,0,0,640,480,0,0,640,480);	
	canvas.createPNGStream().pipe(fs.createWriteStream(tourl));
	setTimeout(function(){
		fs.unlinkSync(picurl); 
	},200);
	
}
 


const data = fs.readFileSync(`./log/task_${$key}.txt`, 'utf-8');
// 等待操作结果返回,然后打印结果
var list=JSON.parse(data);


function do_one(num)
{
	if(!num)
	{
		var num=0;
	}
	var this_main_pic='./截图/'+list[num].path+'/'+list[num].index;
	console.log(this_main_pic);
	main(this_main_pic,function(obj){
		console.log(obj);
		savepic(obj,'./截图/'+list[num].path+'/'+list[num].home,'./截图-ok/'+list[num].path+'/'+list[num].name+'_home.png');
		savepic(obj,'./截图/'+list[num].path+'/'+list[num].h1,'./截图-ok/'+list[num].path+'/'+list[num].name+'_h1.png');
		savepic(obj,'./截图/'+list[num].path+'/'+list[num].h2,'./截图-ok/'+list[num].path+'/'+list[num].name+'_h2.png');
		savepic(obj,'./截图/'+list[num].path+'/'+list[num].os,'./截图-ok/'+list[num].path+'/'+list[num].name+'_os.png');
		savepic(obj,'./截图/'+list[num].path+'/'+list[num].ms,'./截图-ok/'+list[num].path+'/'+list[num].name+'_ms.png');
		savepic(obj,'./截图/'+list[num].path+'/'+list[num].gen,'./截图-ok/'+list[num].path+'/'+list[num].name+'_gen.png');
		
		setTimeout(function(){
			huidu_savepic('./截图-ok/'+list[num].path+'/'+list[num].name+'_home.png','./截图-ok/'+list[num].path+'/'+list[num].name+'_bw.png');
		},2000);
		
		
	});
	
	
	if(num<list.length-1)
	{
		setTimeout(function(){
			do_one(num+1);
		},3000);
	}
	
	
	
	
}



do_one(0);


相关文章

初学nodejs+express,打造cms系统(3)

上次聊到了我的base.js 插入式编程,接着聊编程正题首先是数据库操作类【db_mysql.js】var mysql=require('mysql');  va...

初学nodejs+express,打造cms系统(4)

前面已经改造了基础模块,下面到了页面制作环节。先前的脚手架已经支持ejs了,在views文件夹里出现了测试ejs,下面基本上是锻炼自己仿写能力了。【routes/api.js】var exp...

js预加载loading的另类优化方案

各位做前端的朋友有没做过loading预加载素材的功能,一般游戏开发正常都会用到。其实加载多图的时候我们为了优化体验都是需要做loading效果的。哪些东西需要loading?最常见的就是图片,部分用...

初学nodejs+express,打造cms系统(5)

今天来尝试做上传功能,其实就是一个上传接口。已经跟php完全两样了,两眼一抹黑,直接百度搜索出来拿过来用,也不知道性能如何,反正可以跑通,需要找机会验证一下。【upload.js】//api库&nbs...