How to Join Png with Alpha/Transparency in a Frame in Realtime

Aframe - PNG with transparency in front of entity

You can set the material's alphaTest to 0.5. On A-Frame master (shipping to 0.6.0), you could do:

<a-image material="alphaTest: 0.5"> or perhaps <a-image alpha-test="0.5"></a-image>

On A-Frame 0.5.0, you can do it manually:

<script>
AFRAME.registerComponent('alpha-test', {
dependencies: ['material'],
init: function () {
this.el.getObject3D('mesh').material.alphaTest = 0.5;
}
});
</script>

<a-image src="#transpImage" alpha-test></a-image>

Pen: https://codepen.io/mozvr/pen/jmyVRG

How to merge one RGBA and one RGB images in opencv

Here's how you can do it. I'm not an OpenCV expert, so there might be simpler approaches. Comments in the code explain what it does. The overall idea is:

  1. Extract the alpha channel from the PNG
  2. Extract a piece of the background with the same size
  3. Alpha blend these
  4. Put the result back into the background
import cv2

def alphaMerge(small_foreground, background, top, left):
"""
Puts a small BGRA picture in front of a larger BGR background.
:param small_foreground: The overlay image. Must have 4 channels.
:param background: The background. Must have 3 channels.
:param top: Y position where to put the overlay.
:param left: X position where to put the overlay.
:return: a copy of the background with the overlay added.
"""
result = background.copy()
# From everything I read so far, it seems we need the alpha channel separately
# so let's split the overlay image into its individual channels
fg_b, fg_g, fg_r, fg_a = cv2.split(small_foreground)
# Make the range 0...1 instead of 0...255
fg_a = fg_a / 255.0
# Multiply the RGB channels with the alpha channel
label_rgb = cv2.merge([fg_b * fg_a, fg_g * fg_a, fg_r * fg_a])

# Work on a part of the background only
height, width = small_foreground.shape[0], small_foreground.shape[1]
part_of_bg = result[top:top + height, left:left + width, :]
# Same procedure as before: split the individual channels
bg_b, bg_g, bg_r = cv2.split(part_of_bg)
# Merge them back with opposite of the alpha channel
part_of_bg = cv2.merge([bg_b * (1 - fg_a), bg_g * (1 - fg_a), bg_r * (1 - fg_a)])

# Add the label and the part of the background
cv2.add(label_rgb, part_of_bg, part_of_bg)
# Replace a part of the background
result[top:top + height, left:left + width, :] = part_of_bg
return result

background = cv2.imread('image.jpg')
# Read the image "unchanged" to get the alpha channel as well
label = cv2.imread('image_rgba.png', cv2.IMREAD_UNCHANGED)
result = alphaMerge(label, background, 100, 200)
cv2.imshow("result", result)
cv2.waitKey()

I tested with the following background:

Background

And this foreground:

Foreground

Result as shown by the Python code:

Result

Aframe Image transparency

The renderer won't find out properly which image is in front of another without the material's alpha-test:0.5 property set.

Here is an example with and without the alpha-test



Related Topics



Leave a reply



Submit