光滑的锯齿状像素

时间:2017-09-13 19:40:36

标签: javascript image-processing canvas pixel-manipulation

我使用以下算法在画布上创建了一个捏合滤镜/效果:

// iterate pixels
for (var i = 0; i < originalPixels.data.length; i+= 4) {

    // calculate a pixel's position, distance, and angle
    var pixel = new Pixel(affectedPixels, i, origin);

    // check if the pixel is in the effect area
    if (pixel.dist < effectRadius) {

        // initial method (flawed)
        // iterate original pixels and calculate the new position of the current pixel in the affected pixels
        if (method.value == "org2aff") {

            var targetDist = ( pixel.dist - (1 - pixel.dist / effectRadius) * (effectStrength * effectRadius) ).clamp(0, effectRadius);
            var targetPos  = calcPos(origin, pixel.angle, targetDist);

            setPixel(affectedPixels, targetPos.x, targetPos.y, getPixel(originalPixels, pixel.pos.x, pixel.pos.y));

        } else {

            // alternative method (better)
            // iterate affected pixels and calculate the original position of the current pixel in the original pixels
            var originalDist = (pixel.dist + (effectStrength * effectRadius)) / (1 + effectStrength);
            var originalPos  = calcPos(origin, pixel.angle, originalDist);

            setPixel(affectedPixels, pixel.pos.x, pixel.pos.y, getPixel(originalPixels, originalPos.x, originalPos.y));

        }

    } else {
        // copy unaffected pixels from original to new image
        setPixel(affectedPixels, pixel.pos.x, pixel.pos.y, getPixel(originalPixels, pixel.pos.x, pixel.pos.y));
    }
}

我为此付出了很多努力,我对结果非常满意。不过,我有一个小问题;锯齿状像素。将JS夹点与Gimp的比较:

enter image description here

我不知道我错过了什么。在实际过滤器之后是否需要应用另一个过滤器?或者我的算法完全错了?

我无法在此处添加完整代码(作为SO片段),因为它包含4个base64图像/纹理(总共65k个字符)。相反,这是一个JSFiddle

1 个答案:

答案 0 :(得分:0)

清理结果的一种方法是超级采样。这是一个简单的例子:https://jsfiddle.net/Lawmo4q8/

基本上,不是为单个像素计算单个值,而是在像素内/周围采集多个值样本......

let color =
    calcColor(x - 0.25, y - 0.25) + calcColor(x + 0.25, y - 0.25) +
    calcColor(x - 0.25, y + 0.25) + calcColor(x + 0.25, y + 0.25);

...并以某种方式合并结果。

color /= 4;