【发布时间】:2018-02-22 15:23:18
【问题描述】:
我使用以下算法在画布上创建了捏合滤镜/效果:
// 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 的:
我不知道我错过了什么。我需要在实际过滤器之后应用另一个过滤器吗?还是我的算法完全错误?
我无法在此处添加完整代码(作为 SO sn-p),因为它包含 4 个 base64 图像/纹理(总共 65k 个字符)。取而代之的是JSFiddle。
【问题讨论】:
-
看起来method2是你对your codereview question的Kruga想法的实现——method2和gimp最大的区别是gimp的图像充满了抗锯齿。我想知道,如果方法 2 是针对每个目标像素计算源像素的加权平均值,您能否相应地改变用于目标像素的灰色阴影?这应该接近 gimp 结果。
-
正确。我已经看到了方法 2 在旋转中的作用,并在我的代码中试了一下。正如您和亚历克斯指出的那样,我认为我还需要应用第二个过滤器/插值/抗锯齿,或任何所谓的。首先,我将对这个主题进行广泛的研究。
标签: javascript image-processing canvas pixel-manipulation