Javascript Canvas Pixel Manipulation
Solution 1:
If i guess right, what you want is to change the pixels that are 'near' from a given color to be changed into another color.
Easiest way i see is to use h,s,l color space : in this 'natural' color space, colors that have a similar hue will be similarly perceived by the eye. And you can just 'shift' the hue, while keeping same saturation (== color 'strength'), and lightness.
So process your image point by point : • Convert point r, g, b to hue, saturation, lightness • ? Is the current hue near enough from sourceHue ? ---->> shift it to newHue (keeping same saturation / lightness)
fiddle is here :
You can play around with parameters. The texture you provided has 18 avg hue, so if the source hue is too far from 18, no changes will be done. 8-10 seems a good tolerance.
// 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 inputsvarnormalizedTargetHue= tgtHue / 360;
varnormalizedNewHue= newHue / 360;
varnormalizedTolerance= tolerance / 360;
// create output canvasvarcv2= document.createElement('canvas');
cv2.width = img.width;
cv2.height = img.height;
varctx2= cv2.getContext('2d');
ctx2.drawImage(img, 0, 0);
// get canvad img data varimgData= ctx2.getImageData(0, 0, img.width, img.height);
vardata= imgData.data;
varlastIndex= img.width * img.height * 4;
varrgb= [0, 0, 0];
varhsv= [0.0, 0.0, 0.0];
// loop on all pixelsfor (vari=0; i < lastIndex; i += 4) {
// retrieve r,g,b (! ignoring alpha !) varr= data[i];
varg= data[i + 1];
varb= data[i + 2];
// convert to hsv
RGB2HSV(r, g, b, hsv);
// change color if hue near enough from tgtHuevarhueDelta= 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;
}
EDIT : To get the hue, i consoled.log the hues... ;-) But many (if not all) image software have a color picker that shows hsl. For hsl, i have no specific links. google it, and also play with it within a graphic software. To avoid coding nightmare, i guess you have to decide of a convention on the textures you use, like they are 60 +/- 5 hue or like. So then you only have to decide of the final hue in your game. Detection might be tricky.
Solution 2:
I'm assuming you already know how to do context.getImageData
to get the RGBA pixel data of your images.
The RGBA format that html5 canvas uses by default is not very useful when changing colors. Two visually similar colors often have very different RGB values.
Instead, convert these RGBA colors to HSL format. The "H" in HSL is "hue" which is what we think of as color. You will find similar colored pixels will have similar HSL "Hue" values.
Then you can let the user recolor the image by "shifting" the existing hue values by a constant offset.
Post a Comment for "Javascript Canvas Pixel Manipulation"