如何使背景图像的黑色部分透明?

时间:2016-07-05 08:58:20

标签: javascript css

enter image description here

这是我想要实现的结果。如图所示,QR码由黑色和白色组成,但我希望黑色部分是透明的,以便与外面的背景融合。外面的背景可能会改变,它并不总是绿色。

我尝试使用CSS这样的背景混合模式:

 background-image: url('');
 background-color: rgba(0,0,0,0);
 background-blend-mode: screen;

它什么都不做。

寻求帮助。

2 个答案:

答案 0 :(得分:1)

你有正确的混合模式,我认为背景图像网址是故意省略的,所以我要采用的第一个原因是浏览器兼容性。为此,请查看compatibility chart on caniuse.com,例如。

我建议在这里使用透明的PNG,因为它正是它所代表的内容。即使你让background-blend-mode工作,除非背景完全是黑色的(意思是#000) - 看你的示例图像,情况并非如此,所以你不会得到你的效果想要这样或那样。

我在这里可以想到的另一个问题是,您可能希望QR码与img元素一样,原因如下:

  • 用户可能希望以预期方式保存图像
  • 背景图片不会呈现为块元素,因此根据您的布局,它们可能很容易重叠
  • 背景图片在打印页面时经常被丢弃,所以不应该用于内容
  • 屏幕阅读器可能会忽略背景图像,假设它们只是设计

答案 1 :(得分:1)

您实际上可以通过canvas pixel manipulation实现此效果,但正如其他用户所说,通过图像编辑程序使图像透明会更简单。

我已经创建了一个如何在fiddle here中实现此目的的示例。

此代码首先执行的操作是检索图像元素<img id="code" src="url.png">,构建画布对象,并通过context.drawImage调用将图像内容绘制到画布中。

// Get the image element.
var el = document.getElementById('code');

// Create a canvas and set its width and height.
var canvas = document.createElement('canvas');
canvas.setAttribute('width', 250);
canvas.setAttribute('height', 250);

// Get the canvas drawing context, and draw the image to it.
var context = canvas.getContext('2d');
context.drawImage(el, 0, 0, canvas.width, canvas.height);

接下来,

// Get the canvas image data.
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

// Create a function for preserving a specified colour.
var preserveColor = function(imageData, color) {
    // Get the pixel data from the source.
    var data = imageData.data;
    // Iterate through all the pixels.
    for (var i = 0; i < data.length; i += 4) {
        // Check if the current pixel should have preserved transparency. This simply compares whether the color we passed in is equivalent to our pixel data.
        var preserve = data[i] === color.r
            && data[i + 1] === color.g
            && data[i + 2] === color.b
            && data[i + 3] === color.a;

        // Either preserve the initial transparency or set the transparency to 0.
        data[i + 3] = preserve ? data[i + 3] : 0;
    }
    return imageData;
};

// Get the new pixel data and set it to the canvas context.
var newData = preserveColor(imageData, {r: 255, g: 255, b: 255, a: 255});
context.putImageData(newData, 0, 0);

最后,我们使用document.body.appendChild(canvas);将元素添加到页面中。您也可以使用画布完全替换原始图像元素。

显然,这不是一个理想的解决方案,因为迭代像素数据可能非常慢,只会随着图像尺寸的增大而增加。您也可以轻松更改preserveColor函数,而不是makeTransparent,而指定的颜色变为透明。但是,对于与您指定的颜色类似的颜色,这需要更多逻辑。或者,您可以将其实现为着色器,以便通过将其转移到GPU而不是CPU来提高处理效率。