nodejs裁剪图片
这是个真实的案例,下面脚本是真实跑通的,走过了一些坑,这里来给大家分享一下
首先描述一下场景,我们是做教学软件的,这个是开发一个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);