如果我猜对了,您想要的是将给定颜色“附近”的像素更改为另一种颜色。
我看到的最简单的方法是使用 h,s,l 颜色空间:在这个“自然”颜色空间中,具有相似色调的颜色将被眼睛感知。您可以“改变”色调,同时保持相同的饱和度(==颜色“强度”)和亮度。
因此逐点处理你的图像:
• 将点r、g、b 转换为色调、饱和度、亮度
•?当前的色调与 sourceHue 足够接近吗?
---->> 将其转换为 newHue (保持相同的饱和度/亮度)
小提琴在这里:
http://jsfiddle.net/9GLNP/ http://jsfiddle.net/9GLNP/
您可以尝试使用参数。您提供的纹理的平均色调为 18,因此如果源色调与 18 相差太远,则不会进行任何更改。 8-10 似乎是一个很好的容忍度。
// Provides a new canvas containing [img] where
// all pixels having a hue less than [tolerance]
// distant from [tgtHue] will be replaced by [newHue]
function shiftHue(img, tgtHue, newHue, tolerance) {
// normalize inputs
var normalizedTargetHue = tgtHue / 360;
var normalizedNewHue = newHue / 360;
var normalizedTolerance = tolerance / 360;
// create output canvas
var cv2 = document.createElement('canvas');
cv2.width = img.width;
cv2.height = img.height;
var ctx2 = cv2.getContext('2d');
ctx2.drawImage(img, 0, 0);
// get canvad img data
var imgData = ctx2.getImageData(0, 0, img.width, img.height);
var data = imgData.data;
var lastIndex = img.width * img.height * 4;
var rgb = [0, 0, 0];
var hsv = [0.0, 0.0, 0.0];
// loop on all pixels
for (var i = 0; i < lastIndex; i += 4) {
// retrieve r,g,b (! ignoring alpha !)
var r = data[i];
var g = data[i + 1];
var b = data[i + 2];
// convert to hsv
RGB2HSV(r, g, b, hsv);
// change color if hue near enough from tgtHue
var hueDelta = hsv[0] - normalizedTargetHue;
if (Math.abs(hueDelta) < normalizedTolerance) {
// adjust hue
// ??? or do not add the delta ???
hsv[0] = normalizedNewHue //+ hueDelta;
// convert back to rgb
hsvToRgb(rgb, hsv);
// store
data[i] = rgb[0];
data[i + 1] = rgb[1];
data[i + 2] = rgb[2];
}
}
ctx2.putImageData(imgData, 0, 0);
return cv2;
}
编辑 :
为了获得色调,我安慰并记录了色调...;-)但是很多(如果不是全部)
图像软件有一个显示 hsl 的颜色选择器。
对于 hsl,我没有具体的链接。谷歌一下,也可以玩
它在图形软件中。
为了避免编码噩梦,我想你必须决定一个约定
在你使用的纹理上,比如它们是 60 +/- 5 色调或类似的。那么你只需
必须决定游戏的最终色调。检测可能很棘手。