views:

37

answers:

1

Hi all,

Here's my dilemma: I have to RGBA RAW images: a master image (the first) and a subtitle track (the second), and I want to overlay them in a way based on the alpha channel of the second image: If it's zero, then take the pixels from the second image, if it's 0xFF take the pixels from the first image, otherwise create an overlay of the second image on the first one. Here's the code used for this:

if(frame->bytes[pc + 3] == 0xFF) /* this is NO transparency in the overlay image, meaning: take over the overlay 100% */
{
    pFrameRGB->data[0][pc] = frame->bytes[pc];    // Red
    pFrameRGB->data[0][pc+1] = frame->bytes[pc+1];// Green 
    pFrameRGB->data[0][pc+2] = frame->bytes[pc+2];// Blue 
}
else
if(frame->bytes[pc + 3] != 0) /* this is full transparency in the overlay image, meaning: take over the image 100% */
{
    pFrameRGB->data[0][pc] |= frame->bytes[pc];    // Red
    pFrameRGB->data[0][pc+1] |= frame->bytes[pc+1];// Green 
    pFrameRGB->data[0][pc+2] |= frame->bytes[pc+2];// Blue
    pFrameRGB->data[0][pc+3] = frame->bytes[pc+3]; // Alpha 
}

In the code above the pFrameRGB is the target RGBA image, already containing somet image there, frame->bytes is the "overlay/subtitle" image ... And here comes my question: with some colourful overlay/subtitle images the destination is too colourful... so it's not like the subtitle image is overlayed which effect I want to obtain but you can see a whole range of colors (For example: I have a red/green overlay image with an increasing alpha and I would like the overlay image to look like a "pale" red/green overlay with image below it, however with the approach above I get a lot of colourful pixels on the image below). Do you have a somewhat better approach to this?

Thanks, fritzone

+2  A: 

An equation for doing alpha blending is more complex than just a bitwise or. Supposing a linear response model for RGB a quite common implementation is:

dst_R = (src_R*src_A + dst_R*(255 - src_A)) / 255;
dst_G = (src_G*src_A + dst_G*(255 - src_A)) / 255;
dst_B = (src_B*src_A + dst_B*(255 - src_A)) / 255;
dst_A = min(src_A + dst_A, 255);
6502
Thanks, it's working perfectly.
fritzone