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);

