【问题标题】:HTML5 canvas apply color to image where shape overlaysHTML5 画布将颜色应用于形状覆盖的图像
【发布时间】:2017-06-03 15:48:21
【问题描述】:

我将这张图片绘制到 HTML5 画布上:

我想做的只是将颜色应用于其中的一部分。 我要应用颜色的部分由以下叠加图像定义:

所以,基本上,我想通过叠加来指导我的着色。因此,在覆盖像素与主图像像素相遇的地方,我应该在主图像上应用颜色。至少我认为它是这样工作的。 请注意,叠加层与整个图像匹配,但鞋带除外。

问题是我想在应用颜色时保留主要图像纹理。您可以看到它具有皮革质感和我想要保留的“真实”感觉。

您能告诉我一些实现这一目标的方法或分享一些想法吗?

谢谢!

【问题讨论】:

    标签: html html5-canvas


    【解决方案1】:

    globalCompositeOperation 是你的朋友。

    基本上,您绘制叠加层,然后将 gCO 设置为“source-atop”复合模式,这将使您未来的所有绘图仅停留在已经绘制不透明像素的位置,因此重要的是您的叠加层具有透明部件。
    因此,您只需填充所需命令的矩形,最后绘制原始图像,无论是在后面,还是与我们刚刚创建的新形状混合。

    var ctx = canvas.getContext('2d');
    var loaded = 0;
    function onload(){
       if(++loaded === 2){
           canvas.width = this.width;
           canvas.height = this.height;
           ctx.font = "40px sans-serif";
           draw();
         }
     }
    var original = new Image();
    var overlay = new Image();
    original.onload = overlay.onload = onload;
    original.src = 'https://i.stack.imgur.com/vIKpI.png';
    overlay.src = 'https://i.stack.imgur.com/10Tre.png';
    
    // list of blending modes.
    // Note that destination-over is a composite mode,
    //    which place the new drawings behind the already-there ones
    var currentMode = 0;
    var modes = ['destination-over', 'lighter', 'multiply', 'screen', 'overlay', 'darken',
                 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 
                 'exclusion', 'hue', 'saturation', 'color', 'luminosity' ];
    
    function draw(){
      // switch between different Blending modes
      var mode = modes[currentMode];
      currentMode = (currentMode+1)%(modes.length);
      // clear previous
      ctx.clearRect(0,0,canvas.width, canvas.height);
      // draw our overlay
      ctx.drawImage(overlay, 0,0);
      // this will keep new drawings only where we already have existing pixels
      ctx.globalCompositeOperation = 'source-atop';
      ctx.fillStyle = 'red';
      ctx.fillRect(0,0,canvas.width, canvas.height);
      // now choose between the list of blending modes
      ctx.globalCompositeOperation = mode;
      // draw our original image
      ctx.drawImage(original, 0,0);
      // go back to default
      ctx.globalCompositeOperation = 'source-over';
      // just so we can know which one is shown
      ctx.fillStyle = 'black';
      ctx.fillText(mode, 40,40)
      // do it again
      setTimeout(draw, 1000)
      
      }
    canvas{
        width: 100%;
      }
    <canvas id="canvas"></canvas>

    【讨论】:

    • 感谢您的回答。 “硬光”似乎是最符合我要求的一种。有没有可能我可以在 Internet Explorer 下进行这项工作?我的意思是至少对于现代版本。感谢您的努力!
    • 现代版本应该可以正常工作。对于老年人,混合不起作用,但 compositinf 可以,因此您可以回退到老年人的组合。不久前,我在某处写了一个测试。如果你没有找到它,我可以在大约 10 小时内(睡后)给你。
    • 至少不能在 Internet Explorer 11 下工作。如果您可以分享有关您所指的合成的更多详细信息,那就太好了。再次感谢!
    • 根据caniuse IE确实不支持混合模式...你可以找到一个测试功能here。然后,您可以回退到复合一个 'destination-over',受 IE9 支持。稍微玩一下 globalAlpha + 更改填充样式,您也许可以为 IE 提供一个可接受的后备方案。 (仍然根据 caniuse 的说法,edge 确实支持混合模式)
    • 我最终使用了这个库:github.com/Phrogz/context-blender 虽然它在“hardlight”模式下没有带来相同的结果,但它对于似乎最接近要求的“overlay”模式来说确实如此.感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2013-01-27
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多