画布中的图像操作

Image manipulation in canvas

本文关键字:操作 图像 布中      更新时间:2023-09-26

我在#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');
}

一般情况下,行动是:

  • 我提供要处理的图像的CCD_ 2
  • 等待图像被完全加载
  • 在画布上绘制图像,转换像素,然后将转换后的像素放回画布上
  • 然后我希望返回画布中生成的图像的数据URL

现在,当在开发者工具中,我正在字符串类似于:

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

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

有人能给我指出这里的一个错误吗?

快速回答:由于您使用的是jQuery,您可能会查看jQuery去饱和插件,它可能会满足您的需要。

参考您的代码的较长答案-imgObj.onload是一个异步回调函数,因此在您到达return语句时它还没有执行。您需要从onload回调中执行任何需要post-onload数据URL的代码。一种方法是让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
});