javascript - Canvas change image background color but keep it's "effects" -


i have image need change it's background color, keep "effects" on (on image black dots, white lines etc.)

here's orginal image:

orginal image

i managed change color, keep removing "effects". preview:

enter image description here

here's code:

//let's want red    var r = 255;  var g = 0;  var b = 0;      var imgelement = document.getelementbyid('img');    var canvas = document.getelementbyid('canvas');  canvas.width = imgelement.width;  canvas.height = imgelement.height;    var ctx = canvas.getcontext("2d");  ctx.drawimage(imgelement, 0, 0);    var imagedata = ctx.getimagedata(0, 0, canvas.width, canvas.height);    var data = imagedata.data;    (var = 0; < data.length; += 4) {      if (data[i + 3] !== 0) {          data[i] = r;          data[i + 1] = g;          data[i + 2] = b;          data[i + 3] = data[i + 3];      }  }  ctx.putimagedata(imagedata, 0, 0);
<img src="foo" id="img" />  <canvas id="canvas"></canvas>

how prevent that?

for modern browsers except internet explorer, can use compositing change hue of original image while leaving saturation & lightness unchanged. "recolor" original image while leaving contours intact.

enter image description here

example code works in modern browsers except internet explorer

var canvas=document.getelementbyid("canvas");  var ctx=canvas.getcontext("2d");    var img=new image();  img.onload=start;  img.src="https://dl.dropboxusercontent.com/u/139992952/multple/m449a.png";  function start(){      // create overlay solid #00d9c6 color    var tempcanvas=document.createelement('canvas');    var tempctx=tempcanvas.getcontext('2d');    canvas.width=tempcanvas.width=img.width;    canvas.height=tempcanvas.height=img.height;    tempctx.drawimage(img,0,0);    tempctx.globalcompositeoperation='source-atop';    tempctx.fillstyle='#00d9c6';    tempctx.fillrect(0,0,tempcanvas.width,tempcanvas.height);      //     canvas.width=img.width;    canvas.height=img.height;      // use compositing change hue of original image    ctx.drawimage(img,0,0);    ctx.globalcompositeoperation='hue';    ctx.drawimage(tempcanvas,0,0);      // clean up: reset compositing default    ctx.globalcompositeoperation='source-over';  }
#canvas{border:1px solid red; }
<canvas id="canvas" width=300 height=300></canvas>

since internet explorer not support blend compositing, have manually.

  1. read rgba value of each pixel.
  2. convert rgba value hsl.
  3. shift hue value (the "h" in hsl) difference between blue hue , desired green hue.
  4. convert hue-shifted hsl value rgba value.
  5. write hue-shifted rgba value pixel.

here's example code of manually shifting hue:

important note: manual method works manipulating pixels .getimagedata. therefore must make sure original image hosted on same domain webpage. otherwise, canvas become tainted security reasons , not able use .getimagedata.

var canvas = document.getelementbyid("canvas");  var ctx = canvas.getcontext("2d");    var img = new image();  img.crossorigin = "anonymous";  img.onload = start;  img.src = "https://dl.dropboxusercontent.com/u/139992952/multple/mariostanding.png";    function start() {      ctx.drawimage(img, 0, 0);      ctx.drawimage(img, 150, 0);      // shift blueish colors greenish colors      recolorpants(-.33);  }    function recolorpants(colorshift) {        var imgdata = ctx.getimagedata(150, 0, canvas.width, canvas.height);      var data = imgdata.data;        (var = 0; < data.length; += 4) {          red = data[i + 0];          green = data[i + 1];          blue = data[i + 2];          alpha = data[i + 3];            // skip transparent/semitransparent pixels          if (alpha < 200) {              continue;          }            var hsl = rgbtohsl(red, green, blue);          var hue = hsl.h * 360;            // change blueish pixels new color          if (hue > 200 && hue < 300) {              var newrgb = hsltorgb(hsl.h + colorshift, hsl.s, hsl.l);              data[i + 0] = newrgb.r;              data[i + 1] = newrgb.g;              data[i + 2] = newrgb.b;              data[i + 3] = 255;          }      }      ctx.putimagedata(imgdata, 150, 0);  }      function rgbtohsl(r, g, b) {      r /= 255, g /= 255, b /= 255;      var max = math.max(r, g, b),          min = math.min(r, g, b);      var h, s, l = (max + min) / 2;        if (max == min) {          h = s = 0; // achromatic      } else {          var d = max - min;          s = l > 0.5 ? d / (2 - max - min) : d / (max + min);          switch (max) {              case r:                  h = (g - b) / d + (g < b ? 6 : 0);                  break;              case g:                  h = (b - r) / d + 2;                  break;              case b:                  h = (r - g) / d + 4;                  break;          }          h /= 6;      }        return ({          h: h,          s: s,          l: l,      });  }      function hsltorgb(h, s, l) {      var r, g, b;        if (s == 0) {          r = g = b = l; // achromatic      } else {          function hue2rgb(p, q, t) {              if (t < 0) t += 1;              if (t > 1) t -= 1;              if (t < 1 / 6) return p + (q - p) * 6 * t;              if (t < 1 / 2) return q;              if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;              return p;          }            var q = l < 0.5 ? l * (1 + s) : l + s - l * s;          var p = 2 * l - q;          r = hue2rgb(p, q, h + 1 / 3);          g = hue2rgb(p, q, h);          b = hue2rgb(p, q, h - 1 / 3);      }        return ({          r: math.round(r * 255),          g: math.round(g * 255),          b: math.round(b * 255),      });  }
<p>example shifting color hue .getimagedata</p>  <p>(original: left, recolored: right)</p>  <canvas id="canvas" width=300 height=300></canvas>


Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

python - build a suggestions list using fuzzywuzzy -