skip to Main Content

Is there a way to blend two PNG images to make perfect match when they both have border with alpha on it?

This is an example of the issue that I have:

img {
  position: absolute;
  left: 0px;
  top: 0px;
}

.container {
  height: 512px;
  width: 512px;
}
<div class="container">
  <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
  <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" alt="Cube">
</div>

Or a link to CodePen

The situation is that I have two 3D renders that are saved as PNG’s, and both have alpha border with 50% transparency that will do a perfect match if you merge them in Photoshop and/or After Effects.

But when creating the same situation in HTML/CSS we got a white line between the elements.
After doing some reading about mix-blending-mode and background-blending-mode and do some testing with them it doesn’t seems to help. We think that both of the images (their alpha channels) pre-multiplies with the background and that is why you would get semi transparent line between them (where the border is).

Is there a way to achieve this with CSS, or even maybe JavaScript/jQuery?

Edit: So we won’t get into more comments on images moving and css tricks on that. It is not an option to remove that 1px, or to hide it since the big picture would not have the same look.

4

Answers


  1. There is a minor pixel difference. shift you cube by 1px to the top and tothe left and you are good to go.

    img {
      position: absolute;
      left: 0px;
      top: 0px;
    }
    #cube{
      top:-1px;
      left:-1px;
    }
    .container {
      height: 512px;
      width: 512px;
    }
    <div class="container">
            <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
            <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" id="cube" alt="Cube">
        </div>
    Login or Signup to reply.
  2. Try it help full solution

    i have add only some css .container img:last-child{ left: -1px; top:-1px; position:absolute }

    img {
                position: absolute;
                left: 0px;
                top: 0px;
            }
            
     .container img:last-child{ left: -1px; top:-1px; position:absolute }
     
            .container {
                height: 512px;
                width: 512px;
            }
    <div class="container">
            <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
            <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" alt="Cube">
        </div>
    Login or Signup to reply.
  3. Unfortunately, there’s no way of removing that gap without actually moving the elements around or modifying the actual images. However you, can fake it by applying a drop shadow to each of the images to hide it. Kind of like applying makeup to remove blemishes. This does add a slight blur on the edges of the images, though, so it’s not a perfect solution.

    img {
        position: absolute;
        left: 0px;
        top: 0px;
        filter: drop-shadow(0 0 1px #000);
    }
    
    .container {
        height: 512px;
        width: 512px;
    }
    <div class="container">
        <img src="https://image.prntscr.com/image/VmxphMVDQSu-OXXnHQm1Tg.png" alt="Sphere">
        <img src="https://image.prntscr.com/image/n0cbaO-4QVOk_PQ8ESQRqQ.png" alt="Cube">
    </div>
    Login or Signup to reply.
  4. This isn’t a matter of premultiplying with the background — it’s that along the border you have partially-transparent pixels from both images in the same position, which lets the background bleed through. 50% transparency plus 50% transparency doesn’t equal 100% opaque.

    Rather than fiddling with dropshadows or pixel-adjustments to patch over the problem after the fact, I think you’ll need to adjust the image masks themselves. (I don’t believe there will be a CSS or JS solution to this because there’s no programmatic way to determine what the intended result is.)

    If you’re only stacking two images, this is easy — don’t put any alpha channel on the “bottom” image, put one only on the “top” image, and you’re done.

    If you need to stack more than two (or if you need a mask on the background image to allow the page background to show through), you’ll have a few options:

    1. wherever the border between images would cause this bleed-through, use a 1-bit alpha channel on the “bottom” image in the stack. So if you were stacking the “sphere” image above the “cube” image, the cube would have no partial transparency along the border between sphere and cube, all the pixels along the border would be 100% opaque. The sphere’s partial transparency would smooth out the border so you don’t see a pixelated fringe.
    2. Make the masks on the bottom images one pixel bigger than they currently are. This is the lazy way of accomplishing (1).
    3. pre-multiply the color within the images themselves – not with the background but with the other images that would otherwise overlap. The colors along the border darken to make up for the white color that would otherwise bleed through. (As is probably obvious this one’s a little outside my area of expertise so I can’t suggest exactly how to calculate the precise colors…)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search