我想同时保持形式,影响和轮廓来改变这一形象的背景颜色的图像。
<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] 删除。
我来说两句