接到需求修改马赛克的样式,不知所措~,开始研究,实现效果如下图
重点都在代码注释中,就不多解释了
drawImageToCanvas(image) {
const canvas = document.querySelector('#canvas')
const ctx = canvas.getContext('2d')
return new Promise((resolve, reject) => {
image.onload = function() {
while (this.width > 1360 || this.height > 780) {
this.width = this.width * 0.8 //图片的大小
this.height = this.height * 0.8
}
canvas.width = this.width
canvas.height = this.height
ctx.drawImage(this, 0, 0, this.width, this.height)//宽高为图片尺寸,防止上传的图片大小使图片失真
resolve(ctx)//返回画布对象信息
}
})
},
toEditImage() {//画布初始化
this.editDialogVisible = true
this.isEditImage = true
const image = new Image()//创建图片信息
image.crossOrigin = 'Annoymous'
image.src = this.previewImgObj.fileUrl
const that = this
setTimeout(() => {//延迟开启画布
that.drawImageToCanvas(image).then((ctx) => {//封装的方法,开启canvas
canvas.onmousedown = function(ev){//通过鼠标事件来实现打码效果
var quan = 9; //马赛克的大小
var num = 3; //一次操作包含马赛克的个数
var ev=ev || window.event;
var dx = ev.layerX //鼠标中心位置
var dy = ev.layerY //鼠标中心位置
drawLine(image,dx,dy);
document.onmousemove = function(ev){
// console.log(canvas.offsetTop,canvas.offsetLeft,ev.layerX);
var ev = ev || window.event;
var mx = ev.layerX
var my = ev.layerY
if(Math.pow(dx-mx,2)+Math.pow(dy-my,2)>= Math.pow(quan*num,2)){ //(quan*马赛克个数*2)的平方
drawLine(image,mx,my);
dx = mx;
dy = my;
}
};
document.onmouseup = function(){
that.dataURL = document.querySelector('#canvas').toDataURL('image/png')
document.onmousemove = null;
document.onmouseup = null;
};
function drawLine(obj,dx,dy){
//原始图像
var originalImgData = ctx.getImageData(0,0,canvas.width,canvas.height);
var originalPxData = originalImgData.data;//获取图片像素信息
for(var i=dx-quan*num;i<dx+quan*num;i = i+2*quan+1){//通过循环修改像素颜色
for(var j=dy-quan*num;j<dy+quan*num;j = j+2*quan+1){
//中心点(dx,dy)
if(!((i==dx-quan*num&&j==dy-quan*num)||(i==dx-quan*num&&j==dy-quan*num+2*quan+1)||
(i==dx-quan*num&&j==dy-quan*num+4*quan+2)||(i==dx-quan*num&&j==dy-quan*num+12*quan+6)||
(i==dx-quan*num&&j==dy-quan*num+14*quan+7)||(i==dx-quan*num&&j==dy-quan*num+16*quan+8)||
(i==dx-quan*num+16*quan+8&&j==dy-quan*num)||(i==dx-quan*num+16*quan+8&&j==dy-quan*num+2*quan+1)||
(i==dx-quan*num+16*quan+8&&j==dy-quan*num+4*quan+2)||(i==dx-quan*num+16*quan+8&&j==dy-quan*num+12*quan+6)||
(i==dx-quan*num+16*quan+8&&j==dy-quan*num+14*quan+7)||(i==dx-quan*num+16*quan+8&&j==dy-quan*num+16*quan+8)||
(i==dx-quan*num+2*quan+1&&j==dy-quan*num)||(i==dx-quan*num+4*quan+2&&j==dy-quan*num)||
(i==dx-quan*num+12*quan+6&&j==dy-quan*num)||(i==dx-quan*num+14*quan+7&&j==dy-quan*num)||
(i==dx-quan*num+2*quan+1&&j==dy-quan*num+16*quan+8)||(i==dx-quan*num+4*quan+2&&j==dy-quan*num+16*quan+8)||
(i==dx-quan*num+12*quan+6&&j==dy-quan*num+16*quan+8)||(i==dx-quan*num+14*quan+7&&j==dy-quan*num+16*quan+8))){
for(var x = -quan;x<=quan;x++){
for(var y = -quan;y<=quan;y++){
var xx = i+x;
var yy = j+y;
var pp = yy*canvas.width+xx; //周围的元素。
originalPxData[pp*4+0] = 255;//马赛克颜色
originalPxData[pp*4+1] = 255;
originalPxData[pp*4+2] = 255;
}
}
}
}
}
ctx.putImageData(originalImgData,0,0,0,0,canvas.width,canvas.height);//修改的信息放回画布
}
}
})
}, 20)
},
clearMasic() {//清除刚做的马赛克效果
const canvas = document.querySelector('#canvas')
const ctx = canvas.getContext('2d')
const image = new Image()
image.crossOrigin = 'Annoymous'
image.src = this.previewImgObj.fileUrl
image.onload = function() {
ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
}
},