画布中的图像处理

时间:2012-01-10 22:42:55

标签: javascript jquery canvas image-manipulation

我在#mycontainer中有许多图片,如:

<div id="mycontainer">
    <img src="http://localhost:8080/images/my-image.png" />
    …
</div>

我需要将它们转换成B / W.相当常见的任务,但我没有找到任何适合我的解决方案 - 行动执行存在一些问题。 我现在拥有以下内容:

function grayscale(src) {
    var ctx = document.createElement('canvas').getContext('2d'),
        imgObj = new Image(),
        pixels, i, n, gs, url;

    // wait until the image has been loaded
    imgObj.onload = function () {
        ctx.canvas.width = this.width;
        ctx.canvas.height = this.height;
        ctx.drawImage(this, 0, 0);
        pixels = ctx.getImageData(0, 0, this.width, this.height);
        for (i = 0, n = pixels.data.length; i < n; i += 4) {
            gs = pixels.data[i] * 0.3 + pixels.data[i+1] * 0.59 + pixels.data[i+2] * 0.11;
            pixels.data[i] = gs;   // red
            pixels.data[i+1] = gs;   // green
            pixels.data[i+2] = gs;   // blue
        }
        ctx.putImageData(pixels, 0, 0);
    };
    imgObj.src = src;
    return ctx.canvas.toDataURL('image/png');
}

一般来说,行动是:

  • 我提供要处理的图片的src
  • 等待图片完全加载,
  • 在画布上绘制图像,转换像素并将转换后的像素放回画布上
  • 然后我想要返回画布中生成的图像的数据URL。

现在,在开发人员工具中,我会说:

c = $('#mycontainer').find('img')[0];
grayscale(c.src);

我获取完全透明的默认300px x 150px画布的数据URL,就像脚本中根本不存在imgObj.onload()一样。

请问有人在这里指出我的错误吗?

1 个答案:

答案 0 :(得分:1)

快速回答:既然您正在使用jQuery,那么您可以查看jQuery desaturate plugin,这可能会满足您的需求。

对代码的更长回答 - imgObj.onload是一个异步回调函数,所以当你到达return语句时它不会被执行。您需要在onload回调中执行任何需要发布onload数据网址的代码。一种方法是让grayscale采用回调参数:

function grayscale(src, callback) {
    // ... snip ...

    // wait until the image has been loaded
    imgObj.onload = function () {
        // ... snip ...
        ctx.putImageData(pixels, 0, 0);
        // now fire the callback
        callback(ctx.canvas.toDataURL('image/png'));
    };
    imgObj.src = src;
}

c = $('#mycontainer').find('img')[0];
grayscale(c.src, function(dataUrl) {
    // further stuff with grayscale dataUrl
});