最快的高斯模糊不起作用

时间:2016-05-28 21:21:45

标签: javascript canvas html5-canvas gaussianblur

我不擅长JavaScript并且一直试图让Ivan Kuckir's Fastest Gaussian Blur代码无法正常工作。当我加载页面时,它变得没有响应,所以我将不得不以某种方式关闭窗口。我使用的代码如下。怎么了?

<html>
<head>
<script src="Path_To_GaussianBlur.js"></script>
</head>

<body>
<img id="sourceImage" src="SomeImage_200px_x_200px.jpg" />
<canvas id="canvas1" width="200" height="200" style="border: 1px solid blue"></canvas>
<canvas id="canvas2" width="200" height="200" style="border: 1px solid red"></canvas>

<script>
    document.getElementById("sourceImage").onload = function () {

        var c1 = document.getElementById("canvas1");
        var c2 = document.getElementById("canvas2");

        var ctx1 = c1.getContext("2d");
        var ctx2 = c2.getContext("2d");

        var img = document.getElementById("sourceImage");

        ctx1.drawImage(img, 0, 0);
        ctx2.drawImage(img, 0, 0);

        var source = ctx1.getImageData(0, 0, c1.width, c1.height);
        var target = ctx2.getImageData(0, 0, c2.width, c2.height);

        for (var i = 0; i < source.data.length; i += 4) {
            // red chanel
            gaussBlur_4(source.data[i], target.data[i], c1.width, c1.height, 2);
            // green channel
            gaussBlur_4(source.data[i + 1], target.data[i + 1], c1.width, c1.height, 2);
            // blue channel
            gaussBlur_4(source.data[i + 2], target.data[i + 2], c1.width, c1.height, 2);
        }

        ctx2.putImageData(target, 0, 0);
    };
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

如评论中所述,您需要将rgba数组拆分为单独的通道。你可以用几种方式做到这一点,这里有一个:

分割

var idata = ctx.getImageData(0, 0, w, h), // assumes ctx/w/h to be defined
    rgba = idata.data,
    len = w * h,
    rSrc = new Uint8Array(len),           // source arrays
    gSrc = new Uint8Array(len),
    bSrc = new Uint8Array(len),
    aSrc = new Uint8Array(len),
    // define target arrays the same way as above
    i = 0, offset = 0;

for(; i < len; i++) {
  rSrc[i] = rgba[offset++];
  gSrc[i] = rgba[offset++];
  bSrc[i] = rgba[offset++];
  aSrc[i] = rgba[offset++];
}

现在,您可以使用以与源数组类似的方式设置的目标数组将每个数组传递给blur函数,然后将结果合并回rgba格式。

应用

gaussBlur_4(rSrc, rTrg, w, h, radius);
gaussBlur_4(gSrc, gTrg, w, h, radius);
gaussBlur_4(bSrc, bTrg, w, h, radius);
gaussBlur_4(aSrc, aTrg, w, h, radius);

其他提示:如果你正在使用图像(如在照片中),你可以跳过模糊alpha通道,因为没有(或者在技术上,在画布中完全不透明)。

合并

要合并,只需执行以下操作:

for(i = 0, offset = 0; i < len; i++) {
  rgba[offset++] = rTrg[i];
  rgba[offset++] = gTrg[i];
  rgba[offset++] = bTrg[i];
  rgba[offset++] = aTrg[i]; // or just increase offset if you skipped alpha
}

ctx.putImageData(idata, 0, 0);

由于许可证冲突,可以在此 fiddle 中找到正在运行的示例(here是使用32位方法的替代拆分/合并)。< / p>