Jc.
Jc.

Reputation: 214

How to make the black part of the background image transparent?

enter image description here

Here's the result I want to realize.As is shown, the QR Code consists of black and white , but I want the black part to be transparent so as to blend with the background outside. The background outside may change, it's not always green.

I've tried to use background blend mode with CSS like this:

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

It does nothing.

Thx for help.

Upvotes: 3

Views: 2160

Answers (2)

Monica Olejniczak
Monica Olejniczak

Reputation: 1156

You can actually achieve this effect through canvas pixel manipulation, but as other users have stated it would be simpler to make your image transparent through an image editing program.

I have created an example of how to achieve this in the fiddle here.

What this code first does is retrieve the image element <img id="code" src="url.png">, construct a canvas object and draw the contents of the image into the canvas through the context.drawImage call.

// 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);

Next,

// 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);

Finally, we add the element to our page using document.body.appendChild(canvas);. You can alternatively completely replace the original image element with the canvas.

Obviously, this isn't an ideal solution because iterating through pixel data can be very slow and only increases with large image sizes. You could also easily change the preserveColor function to instead do the opposite with makeTransparent where the color specified becomes transparent. However, this would require a bit more logic for colors that are similar to the one you specify. Alternatively, you could implement this as a shader so that the processing is more efficient by shifting it to the GPU instead of the CPU.

Upvotes: 1

TheThirdMan
TheThirdMan

Reputation: 1522

You have the correct blend mode, and I assume the background-image url is omitted on purpose, so the first reason I would resort to is browser compatibility. For this, take a look at the compatibility chart on caniuse.com, for example.

I'd suggest using a transparent PNG here, as that's exactly what it's indended for. Even if you get background-blend-mode to work, unless the background is perfectly black (meaning #000) - looking at your example image, that isn't the case, so you wouldn't get the effect you want one way or the other.

Another issue I can think of here is that you probably want that QR code as in img element, for the following reasons:

  • a user may want to save the image in the intended way
  • background images don't render as block elements, so depending on your layout, they may be easily overlapped
  • background images often get discarded when printing pages, so they shouldn't be used for content
  • screen readers will likely ignore backgound images, assuming they're just design

Upvotes: 1

Related Questions