我正在将图片加载到画布中;我drawImage(),将getImageData()存储到一个变量中进行操作。我希望能够多次操作数据,例如:添加/删除各种过滤器。如何存储数据,以便每次使用putImageData()绘制图片时都更新数据?
基本上,我认为我误解了getImageData的使用或使用不正确。我的想法是,对图片执行的任何操作都可以运行getImageData并更新包含信息的变量,然后使用它“重绘”图片。
例:
在下面的代码段中,假设我运行了一个将图片变成黑白的函数。我还有另一个功能可以在单击图片时调整图片的大小。当我调整图片大小时,黑白滤镜消失了。保留图片信息我在做错什么?
//Read in picture
var reader = new FileReader();
reader.onload = function leDraw(e){
imgObj = new Image();
picWidth = canvas.width/2;
picHeight = canvas.height/2;
imgObj.src = e.target.result;
newX = 0;
newY = 0;
ctx.drawImage(imgObj,0,0, picWidth, picHeight);
imageData = ctx.getImageData(newX,newY, canvas.width, canvas.height);
originalCopy = ctx.getImageData(newX,newY, picWidth, picHeight);
data = imageData.data;
function resize(val){ Resizes picture
userPicHeight = document.getElementById("cSelect").value;
userPicWidth = document.getElementById("cSelect").value;
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.drawImage(imgObj, newX, newY, userPicWidth, userPicHeight);
window['imageData'] = ctx.getImageData(newX,newY, userPicWidth, userPicHeight);
ctx.putImageData(imageData, newX, newY);
};
最佳答案
imageData
是画布像素数据的快照。在您的情况下,它是整个画布的(彩色的,不是黑白的)像素数据。
因此,当您执行.putImageData(imageData...)
时,未更改的快照显示将再次显示在画布上。
如果要重新缩放图片的黑白版本:
在用var memCanvas = document.createElement
创建的新画布上绘制彩色图像。将画布调整为图像尺寸。画布可以保留在内存中-无需将其appendChild
放入DOM中。
使用getImageData
将滤镜应用于新画布,修改像素数据putImageData
。现在,您有了一个“图像画布”,以后可以用来调整大小等。
将图像画布绘制到可见的画布上:context.drawImage(memCanvas,0,0)
。是的,memCanvas可以是drawImage
的图像源。
要缩放图像的黑白版本,只需清除画布,使用context.scale
缩放画布,然后使用drawImage(memCanvas,0,0)
绘制缩放的黑白图像
如果以后要重新调整黑白图像的大小,可以再次执行步骤4。
示例代码和使用灰度滤镜的演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png";
function start(){
// create a grayscale image-canvas
var grayImg=makeFilteredImageCanvas(img,grayscaleFilter);
// scale the visible canvas
ctx.scale(1.25,1.25);
// draw the grayscale imag-canvas on the canvas
// (the result will be scaled)
ctx.drawImage(grayImg,0,0);
}
function makeFilteredImageCanvas(img,filter){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
iw=c.width=img.width;
ih=c.height=img.height;
cctx.drawImage(img,0,0);
filter(cctx);
return(c);
}
function grayscaleFilter(context){
var canvas=context.canvas;
var w=canvas.width;
var h=canvas.height;
var imageData=context.getImageData(0,0,w,h);
var data=imageData.data;
for(var i=0;i<data.length;i+=4){
var gray=data[i]*0.33+data[i+1]*0.5+data[i+2]*0.16;
data[i]=data[i+1]=data[i+2]=gray;
}
context.putImageData(imageData,0,0);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h4>Grayscale image scaled up by 25%</h4>
<canvas id="canvas" width=300 height=300></canvas>
<h4>Original Image:</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png' crossOrigin='anonymous'>