简体   繁体   English

画布/照片-getImageData不起作用

[英]Canvas/Photo - getImageData not working

I am loading a picture into a canvas; 我正在将图片加载到画布中; I drawImage(), store getImageData() into a variable for manipulating. 我drawImage(),将getImageData()存储到一个变量中进行操作。 I would like to be able to manipulate the data many times for example: add/remove various filters. 我希望能够多次操作数据,例如:添加/删除各种过滤器。 How can I store the data so that it updates every time I draw the picture with putImageData()? 如何存储数据,以便每次使用putImageData()绘制图片时都更新数据?

Basically, I think I am misunderstanding the use of getImageData or using it incorrectly. 基本上,我认为我误解了getImageData的使用或使用不正确。 My thought was that any manipulation that was done to the picture, I could run getImageData and update the variable that contained the information, and use it to "redraw" the picture. 我的想法是,对图片执行的任何操作都可以运行getImageData并更新包含信息的变量,然后使用它“重绘”图片。

Example: In the snippet below Lets say I run a function that turn the picture black and white. 示例:在下面的代码段中,假设我运行了一个将图片变成黑白的函数。 I have another function that resizes the picture when it is clicked. 我还有另一个功能可以在单击图片时调整图片的大小。 When I resize the picture the the black and white filter disappears . 当我调整图片大小时,黑白滤镜消失了 What am I doing wrong to keep the information of the picture? 保留图片信息我在做错什么?

//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 is a snapshot of canvas pixel data. imageData是画布像素数据的快照。 In your case it's the entire canvas's (colored--not B&W) pixel data. 在您的情况下,它是整个画布的(彩色的,不是黑白的)像素数据。

So when you do .putImageData(imageData...) the unaltered snapshow is again displayed on the canvas. 因此,当您执行.putImageData(imageData...) ,未更改的快照显示将再次显示在画布上。

If you want to rescale a B&W version of your picture: 如果要重新缩放图片的黑白版本:

  1. Draw your color image on a new canvas created with var memCanvas = document.createElement . 在使用var memCanvas = document.createElement创建的新画布上绘制彩色图像。 Size the canvas to the image size. 将画布调整为图像尺寸。 The canvas can be left in-memory -- no need to appendChild it into the DOM. 画布可以保留在内存中-无需将其appendChild到DOM中。

  2. Apply the filter to the new canvas with getImageData , modify pixel data, putImageData . 使用getImageData将滤镜应用于新画布,修改像素数据putImageData Now you have an "image-canvas" that you can later use to resize, etc. 现在,您有了一个“图像画布”,以后可以用来调整大小等。

  3. Draw the image-Canvas onto the visible canvas: context.drawImage(memCanvas,0,0) . 将图像画布绘制到可见的画布上: context.drawImage(memCanvas,0,0) Yes, the memCanvas can be an image source for drawImage . 是的,memCanvas可以是drawImage的图像源。

  4. To scale the B&W version of the image, just clear the canvas, scale the canvas with context.scale & then draw the scaled B&W image with drawImage(memCanvas,0,0) 要缩放图像的黑白版本,只需清除画布,使用context.scale缩放画布,然后使用drawImage(memCanvas,0,0)绘制缩放的黑白图像。

If you later want to re-rescale the B&W image, you can do Step#4 again. 如果以后要重新调整黑白图像的大小,可以再次执行步骤4。

Example code and a Demo using a grayscale filter: 示例代码和使用灰度滤镜的演示:

 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'> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM