Hue change

HTML

<canvas id='cv' width='480' height='200'></canvas>
<br>
<br>
<br>
<br>Source Hue selection :
<input id='sourceHueRange' type='range' min='0' max='360' step='1' value='18' style='width:240px;align:left;'></input>
<br>
<br>Target Hue selection :
<input id='targetHueRange' type='range' min='0' max='360' step='1' value='100' style='width:240px;align:left;'></input>
<br>
<br>Tolerance :
<input id='toleranceRange' type='range' min='2' max='20' step='1' value='10' style='width:80px;align:left;'></input>

JavaScript

var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
ctx.font = '16px Arial';

// setup U.I.
var sourceHueRange = document.getElementById('sourceHueRange');
var targetHueRange = document.getElementById('targetHueRange');
var toleranceRange = document.getElementById('toleranceRange');
sourceHueRange.onchange = hueSelectionChanged;
targetHueRange.onchange = hueSelectionChanged;
toleranceRange.onchange = hueSelectionChanged;

// load example image
//   using Base64 to avoid CORS issue
var img64;
setImg64();
var img = new Image();
img.src = img64;

// draw source image
ctx.drawImage(img, 0, 0);

// first update
hueSelectionChanged();


// 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 normalizesTargetHue = tgtHue / 360;
    var normaizedNewHue = newHue / 360;
    var normalzedTolerance = 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] - normalizesTargetHue;
        if (Math.abs(hueDelta) < normalzedTolerance) {
            // adjust hue
            hsv[0] = normaizedNewHue + hueDelta;
            // convert back to rgb
           ...