2014-07-15 36 views
0

中的颜色混合模式我具有带颜色的纹理图像。我想要的是改变图像的颜色,但保留其纹理。我已经知道如何逐个像素地获取图像的数据(rgb值)。 这里的样本图像:enter image description here使用javascript和HTML5 canvas以指定的颜色着色或替换纹理图像的颜色。类似于PS

我希望它是彩色的到这些:enter image description here

+0

我想,如果改变颜色是你的唯一要求,那么CSS滤镜可以做你的工作。 – j809

+0

是的,我想改变颜色,但使用JavaScript或jQuery,因为颜色将由user.im使用html5画布 – user2356747

+0

指定看看这里:http://html5-demos.appspot.com/static/css/ filters/index.html,你可以使用'-webkit-filter',这是一个非常近的事情。 – j809

回答

2

这里是一个互动的解决方案。从localhost运行它并指定一个有效的图像。

enter image description here

<!DOCTYPE html> 
<html> 
<head> 
<script> 
function byId(e){return document.getElementById(e);} 
function newEl(tag){return document.createElement(tag);} 
function newTxt(txt){return document.createTextNode(txt);} 

window.addEventListener('load', mInit, false); 

function mInit() 
{ 
    var srcImg = byId('srcImg'); 

    byId('hueSlider').style.width = srcImg.width + "px"; 
    var destImg = byId('dstImg'); 
    destImg.width = srcImg.width; 
    destImg.height = srcImg.height; 
} 

function colorize() 
{ 
    var curHue = byId('hueSlider').value; 
    var curSat = byId('satSlider').value;///100.0; 
    var curLum = byId('lumSlider').value/100.0; 
    byId('hueVal').innerHTML = curHue; 
    byId('satVal').innerHTML = curSat; 
    byId('lumVal').innerHTML = curLum; 

    var dst = byId('dstImg'); 
    var dstCtx = dst.getContext('2d'); 
    var img = byId('srcImg'); 
    dstCtx.drawImage(img, 0, 0); 

    var dstImgData = dstCtx.getImageData(0,0,dst.width,dst.height); 
    var i, j, r,g,b,hsl,rgb, index; 
    if (byId('colCheckBox').checked) 
    { 
     console.log('colourizing'); 
     for (j=0; j<dst.height; j++) 
     { 
      for (i=0; i<dst.width; i++) 
      { 
       index = (i + j*dst.width) * 4;    // 4 bytes/pixel, set index to point to r component of x,y in dst image 
       r = dstImgData.data[index+0]; 
       g = dstImgData.data[index+1]; 
       b = dstImgData.data[index+2]; 
       hsl = rgb2hsl (r, g, b); 

       hsl.h = curHue; 
       //if (hsl.h > 359) 
       // hsl.h -= 360; 
       hsl.s = curSat; 

       hsl.l *= curLum; 

       rgb = hsl2rgb(hsl.h, hsl.s, hsl.l); 
       dstImgData.data[index+0] = rgb.r; 
       dstImgData.data[index+1] = rgb.g; 
       dstImgData.data[index+2] = rgb.b; 
      } 
     } 
     dstCtx.putImageData(dstImgData,0,0); 
    } 
} 

// code taken from nichabi.com 
function hsl2rgb (h, s, l) { 

    var r, g, b, m, c, x 

    if (!isFinite(h)) h = 0 
    if (!isFinite(s)) s = 0 
    if (!isFinite(l)) l = 0 

    h /= 60 
    if (h < 0) h = 6 - (-h % 6) 
    h %= 6 

    s = Math.max(0, Math.min(1, s/100)) 
    l = Math.max(0, Math.min(1, l/100)) 

    c = (1 - Math.abs((2 * l) - 1)) * s 
    x = c * (1 - Math.abs((h % 2) - 1)) 

    if (h < 1) { 
     r = c 
     g = x 
     b = 0 
    } else if (h < 2) { 
     r = x 
     g = c 
     b = 0 
    } else if (h < 3) { 
     r = 0 
     g = c 
     b = x 
    } else if (h < 4) { 
     r = 0 
     g = x 
     b = c 
    } else if (h < 5) { 
     r = x 
     g = 0 
     b = c 
    } else { 
     r = c 
     g = 0 
     b = x 
    } 

    m = l - c/2 
    r = Math.round((r + m) * 255) 
    g = Math.round((g + m) * 255) 
    b = Math.round((b + m) * 255) 

    return { r: r, g: g, b: b } 
} 


// code taken from nichabi.com 
function rgb2hsl (r, g, b) 
{ 
    var max, min, h, s, l, d 
    r /= 255 
    g /= 255 
    b /= 255 
    max = Math.max(r, g, b) 
    min = Math.min(r, g, b) 
    l = (max + min)/2 
    if (max == min) { 
     h = s = 0 
    } else { 
     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 
    } 
    h = Math.floor(h * 360) 
    s = Math.floor(s * 100) 
    l = Math.floor(l * 100) 
    return { h: h, s: s, l: l } 
} 


</script> 
<style> 
body 
{ 
    background: #888; 
} 
#hueVal, #satVal, #lumVal 
{ 
    font-size: 0.8em; 
    font-weight: bold; 
    display: inline; 
} 
</style> 
</head> 
<body> 
<img id='srcImg' src='handlebars.png'/><canvas id='dstImg'></canvas> 
<br> 
<label><input type='checkbox' id='colCheckBox' onchange='colorize()' />Colourize</label> 
<br> 
Hue<input id='hueSlider' onchange='colorize()' type='range' min='0' max='359'/><div id='hueVal'></div><br> 
Saturation<input id='satSlider' onchange='colorize()' type='range' value='50' min='0' max='100'/><div id='satVal'></div><br> 
Luminance<input id='lumSlider' onchange='colorize()' type='range' min='0' max='200'/><div id='lumVal'></div> 
</body> 
</html> 
+0

感谢你的建议。我已经想过这样做了,但对我的要求是,只需输入颜色(十六进制值),然后图像将根据指定的颜色着色。感谢,这将帮助我很多。 – user2356747

+0

没关系。既然你可以将RGB颜色映射到HSL,我想它可能仍然适用于你。我想你只需要改变源图像的H通道来匹配输入的#rrggbb颜色的H通道。不确定,太累了。干杯。 :) – enhzflep