Javascript canvas pixel manipulation

强颜欢笑 提交于 2020-01-05 02:30:07

问题


I have product images and each image has two configurable areas as below: 1. background 2. Foreground

I have to develop a feature where customer can change the color of both areas and save the design.

My problem is, i am traversing the image to read old pixel value and change it with new selected color.

Bit old pixel values are not consistent. There is textured effect on the image, which is causing the pixel value to be changed at every pixel.

How can i achieve the desired the functionality?

or, if you can suggest me any other approach, that will be great.

sample image link: http://developersbench.com/canvas/img/design_2.jpg


回答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 :

http://jsfiddle.net/9GLNP/

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 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;
}

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.




回答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.

A Demo: http://jsfiddle.net/m1erickson/326yc/



来源:https://stackoverflow.com/questions/24218783/javascript-canvas-pixel-manipulation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!