如何在不更改图案的情况下更改HTML5画布中图像的颜色

柴ym

我想同时保持形式,影响和轮廓来改变这一形象的背景颜色的图像

<canvas id="canvas01" width="1200" height="800"></canvas>
<script>
    function drawImage(imageObj,x, y, width, height){
        var canvas = document.getElementById('canvas01');
        var context = canvas.getContext('2d');
        context.drawImage(imageObj, x, y, width, height);
    }
    var image = new Image();
    image.onload = function(){
        drawImage(this, 400, 100, 320, 450);
    };
    image.src ="images/658FFBC6.png";
</script>
用户名

亮度保存

冒着看起来与现有答案相似的风险,我想指出一点,但是使用稍有不同的方法是很重要的区别。

关键是要保留图像中的亮度分量(例如,在这种情况下为阴影细节,皱纹等),因此需要两个步骤来使用混合模式通过globalCompositeOperation(或使用RGB和图像之间的转换的手动方法)来控制外观。HSL颜色空间(如果必须支持旧版浏览器):

  • saturation”:将更改下一个绘制元素的色度(强度,饱和度),并将其应用于画布上的现有内容,但保留亮度和色相。
  • hue”:将从下一个源获取色度和亮度,但根据下一个绘制的元素更改色相或颜色(如果需要)。

由于这些是混合模式(忽略Alpha通道),我们还需要使用合成作为最后一步来裁剪结果。

所述color混合模式可以太使用,但它会改变亮度可能会或可能不是期望的。在许多情况下,差异可能很小,但根据丢失亮度/阴影清晰度的目标色度和色相,差异也非常明显。

因此,要获得既保持亮度又保持色度的高质量效果,这些或多或少是主要步骤(假设画布为空):

// step 1: draw in original image
ctx.globalCompositeOperation = "source-over";
ctx.drawImage(img, 0, 0);

// step 2: adjust saturation (chroma, intensity)
ctx.globalCompositeOperation = "saturation";
ctx.fillStyle = "hsl(0," + sat + "%, 50%)";  // hue doesn't matter here
ctx.fillRect(0, 0);

// step 3: adjust hue, preserve luma and chroma
ctx.globalCompositeOperation = "hue";
ctx.fillStyle = "hsl(" + hue + ",1%, 50%)";  // sat must be > 0, otherwise won't matter
ctx.fillRect(0, 0, c.width, c.height);

// step 4: in our case, we need to clip as we filled the entire area
ctx.globalCompositeOperation = "destination-in";
ctx.drawImage(img, 0, 0);

// step 5: reset comp mode to default
ctx.globalCompositeOperation = "source-over";

50%的亮度(L)将保持原始的亮度值。

现场例子

单击复选框以查看对结果的影响。然后使用不同的色度和色调设置进行测试。

var ctx = c.getContext("2d");
var img = new Image(); img.onload = demo; img.src = "//i.stack.imgur.com/Kk1qd.png";
function demo() {c.width = this.width>>1; c.height = this.height>>1; render()}

function render() {
  var hue = +rHue.value, sat = +rSat.value, l = +rL.value;
  
  ctx.clearRect(0, 0, c.width, c.height);
  ctx.globalCompositeOperation = "source-over";
  ctx.drawImage(img, 0, 0, c.width, c.height);

  if (!!cColor.checked) {
    // use color blending mode
    ctx.globalCompositeOperation = "color";
    ctx.fillStyle = "hsl(" + hue + "," + sat + "%, 50%)";
    ctx.fillRect(0, 0, c.width, c.height);
  }
  else {
    // adjust "lightness"
    ctx.globalCompositeOperation = l < 100 ? "color-burn" : "color-dodge";
    // for common slider, to produce a valid value for both directions
    l = l >= 100 ? l - 100 : 100 - (100 - l);
    ctx.fillStyle = "hsl(0, 50%, " + l + "%)";
    ctx.fillRect(0, 0, c.width, c.height);
    
    // adjust saturation
    ctx.globalCompositeOperation = "saturation";
    ctx.fillStyle = "hsl(0," + sat + "%, 50%)";
    ctx.fillRect(0, 0, c.width, c.height);

    // adjust hue
    ctx.globalCompositeOperation = "hue";
    ctx.fillStyle = "hsl(" + hue + ",1%, 50%)";
    ctx.fillRect(0, 0, c.width, c.height);
  }
  
  // clip
  ctx.globalCompositeOperation = "destination-in";
  ctx.drawImage(img, 0, 0, c.width, c.height);

  // reset comp. mode to default
  ctx.globalCompositeOperation = "source-over";
}

rHue.oninput = rSat.oninput = rL.oninput = cColor.onchange = render;
body {font:16px sans-serif}
<div>
  <label>Hue: <input type=range id=rHue max=359 value=0></label>
  <label>Saturation: <input type=range id=rSat value=100></label>
  <label>Lightness: <input type=range id=rL max=200 value=100></label>
  <label>Use "color" instead: <input type=checkbox id=cColor></label>
</div>
<canvas id=c></canvas>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在具有更好插值的html5画布上缩放图像?

如何在html5画布中绘制椭圆形?

调整HTML5画布中图像的大小

密谋:如何在不更改图形数据源的情况下更改图例?

如何在默认情况下将系列标签设置为false并更改图表中系列标签文本的颜色

在HTML5画布中处理大图像

立即显示对HTML5画布的更改

如何将HTML5画布作为图像存储在框架列表中?

如何在HTML5画布上使用图像而不在页面上预先放置图像?

HTML5画布图案绘制延迟

如何在没有像素模糊的情况下调整html5画布的大小

如何在HTML5画布中显示多个外部SVG图形

如何在HTML5画布的矩形中添加滚动条?

HTML5 Canvas:更改图像颜色

如何在不更改图像的情况下反转x轴?

如何在HTML5画布上绘制背景图像

在这种情况下,如何在HTML5画布上重画一个圆?(方法调用与直接使用上下文对象相比)

如何在不更改GIMP中的打印尺寸的情况下更改图片的PPI

如何在Android Webview中捕获html5画布?

如何在Safari iOS中缩放HTML5画布中的表情符号?

html5画布图案尺寸波动

HTML5画布将颜色应用于形状重叠的图像

html5画布包含颜色选择

如何在html5画布中为自定义线制作线宽

如何在不更改框阴影颜色的情况下更改 svg 颜色

如何在不更改图像的情况下将 3d RGB NumPy 数组转换为浮动?

如何在不更改 python matplotlib 中的热图的情况下更改颜色条的值?

如何在html5画布上放置重叠图像?

如何在不更改文本颜色本身的情况下更改输入字段中打字机的颜色?