HTML5画布让黑色透明化

6
我有许多带有黑色背景的图片,这里是一个例子: enter image description here 通过JavaScript忽略黑色(#000000)并在画布上绘制是否可能?使它看起来像这样: enter image description here 基本上想把黑色像素变成透明通道。

2
我不知道。但是你可以使用ImageMagick离线转换所有图像:convert withblack/x.png -transparent black transparent/x.png - Amadan
是的,这是可行的。您可以在画布上加载图像,然后访问图像数据并覆盖您想要透明化的颜色。请参阅此处的指南:https://hmp.is.it/creating-chroma-key-effect-html5-canvas/。 - Tennyson H
@Amadan 谢谢你!我认为这可能是最好的方法,因为我有成百上千个这些小黑色 BG 图像。将它们全部作为透明 PNG 下载可能对客户端的负荷更少。我看到我可以把所有数百张图像放在一个文件夹中并运行 mogrify -transparent black *.png ,就大功告成了! - Sosa
@Sosa。批量预处理是最好的选择。如果您正在进行批量处理,请确保不要意外将所需瓷砖的黑色部分转换为透明。如果遇到意外透明问题,可以使用HTML5画布来用透明度填充黑色边缘。您可以在开发机器上执行此操作一次(而不是每次在客户端上执行)。 - markE
4个回答

8
所以您需要遍历所有像素并更改所有黑色像素的alpha值。
此代码创建一个缓冲区(空画布)来绘制原始图像。完成后,它获取此缓冲区画布的所有像素,然后迭代所有像素并检查其值。我将红色、蓝色和绿色值相加,以查看它们是否小于10(以防一些像素不是纯黑色0),但在人眼中看起来是黑色的。如果小于10,则仅将该像素的alpha值变为0。 https://jsfiddle.net/0kuph15a/2/
var canvas = document.getElementById('main');

var ctx = document.getElementById('main').getContext('2d');
var tile = new Image();
tile.src = document.getElementById('image').src;
tile.onload = function() {
    draw(tile);
}

function draw(img) {
    var buffer = document.createElement('canvas');
    var bufferctx = buffer.getContext('2d');
    bufferctx.drawImage(img, 0, 0);
    var imageData = bufferctx.getImageData(0,0,buffer.width,  buffer.height);
    var data = imageData.data;
    var removeBlack = function() {
        for (var i = 0; i < data.length; i += 4) {
            if(data[i]+ data[i + 1] + data[i + 2] < 10){ 
                data[i + 3] = 0; // alpha
            }
        } 
        ctx.putImageData(imageData, 0, 0); 
    }; 
 removeBlack(); 
} 

如果您确定只使用 #000 黑色,那么您可以轻松地将这行代码 if(data[i]+ data[i + 1] + data[i + 2] < 10){ 更改为 if(data[i]+ data[i+1] + data[i+2]==0){


使用 getImageData 获取并将所有黑色像素变为透明是一个不错的开始。 :-) 可能在钻石形状内部有所需的黑色像素,因此您可以改进解决方案,仅影响钻石外部的黑色像素。例如:从左上角开始,行==0,列==0。向右移动并清除所有黑色像素,直到达到非黑色像素。从行==1,列==0重新开始。向右移动并清除所有黑色像素,直到达到非黑色像素...以此类推。从所有4个角开始重复此过程。 - markE

4
你可以使用混合模式来实现这一点。
将上下文的 globalCompositeOperation 更改为 screen,就可以得到该结果。以下是一个示例:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");


var image = new Image();
image.src = "https://images.blogthings.com/thecolorfulpatterntest/pattern-4.png";

image.onload = function() {
  context.drawImage(image, 0, 0, canvas.width, canvas.height);

  var blackImage = new Image();
  blackImage.src="http://www.printmag.com/wp-content/uploads/Sillitoe-black-white.gif";
  blackImage.onload = function(){
    context.globalCompositeOperation = "screen";
    context.drawImage(blackImage, 0, 0, canvas.width, canvas.height);
  }

};
<canvas id="canvas" width="300" height="250"></canvas>

<hr/>
<h1>Images used:</h1>

<img src="https://images.blogthings.com/thecolorfulpatterntest/pattern-4.png"/>

<img src="http://www.printmag.com/wp-content/uploads/Sillitoe-black-white.gif"/>


谢谢您的回复!我在我的主要代码上尝试了一下,但好像没有起作用。这里有一个例子 jsfiddle - Sosa
画布的背景是黑色的。JSFiddle - Filipe
我知道默认情况下它会填充黑色,但我想要真正的透明度。 - Sosa
@Filipe 我在给定的解决方案中遇到了问题。最终输出的绘图颜色变得非常浅,不是原始颜色。请参见 https://jsfiddle.net/eonjs623/2/ 中的示例,你能帮我恢复原始绘图颜色吗? - Sankar

0

将图片保存为 .svg 文件怎么样?从那里你可以更改所有的颜色和其他设置。


0
Felipe的回答解决了我的问题。Alpha像素操作不能用于在同一时间将多个图像添加到相同上下文中以保留alpha透明度(例如,将每4个像素设置为0)。

例如:

this.ctx1.putImageData(output, 0, 0); // without setting the context's globalCompositeOperation, this image is written over by the next putImage operation
this.ctx1.putImageData(output, 20, 0);

请点击此处查看混合选项。https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接