0

I am implementing an alpha blending, and one of the examples I came across used this format. I am confused why the division by 256 and why isn't there inv_alpha in red and blue channels

int pixel,vga_pixel;
int alpha, blue, green, red, pixel;

int height = 1296;
int width = 968;
int x, y;

for (y = 0; y <= height; y++){
    for (x = 0; x <= width; x++){
        pixel = *(img.memloc + x + y);
            //0xff gets the first 8 bits, in this case red  
            red = pixel & 0xff; 

            //shift by 8 to get rid of red then AND  to get first 8, here green
            green = pixel >> 8 & 0xff; 

            blue = pixel >> 16 & 0xff;

            alpha = pixel >> 24 & 0xff;
            int inv_alpha = 0xff - alpha; // 1-alpha

            int vga_red = (red*(int)alpha);
            int vga_green = (green*(int)alpha + inv_alpha/256);
            int vga_blue = (blue*(int)alpha);
            int vga_alpha = 0xff;

            int vga_pixel = vga_alpha << 24 | vga_blue << 16 | vga_green << 8 | vga_red;            
    }
} 

Can anyone clarify if this is a valid method, and why?

Ziezi
  • 6,375
  • 3
  • 39
  • 49
  • Perhaps you should ask what difference the `inv_alpha/256` makes, integer division between a number between 0 and 255 (I assume) and 256, gives .... 0. My guess is that you can simply ignore, and remove, it. – Tommy Andersen Oct 27 '15 at 08:07
  • I was under the impression that the actual formula is: vga_red= red*alpha +inv_alpha*red. is this wrong? – pointnotfoe Oct 27 '15 at 08:13
  • The formula is red = source_red * alpha + destination_red * inv_alpha. There is no blending going on in that code because there is only one set of RGB values. – samgak Oct 27 '15 at 08:47

2 Answers2

2

It look's like you've mixed the formulas from integer and floating point blending. For example the vga_red should probably become 255 if both red and alpha is, so it would be closer to (red*alpha)/255, but probably you should probably ensure correct rounding by using (red*alpha+127)/255.

The dividing inv_alpha with 256 would always yield zero so it's probably wrong, I'd guess that you want the result to be green if alpha is 255 and 255 if alpha is 0. So it would become something like (green*alpha+127)/255 + inv_alpha.

skyking
  • 13,817
  • 1
  • 35
  • 57
0

The formula for alpha blending is C = alpha_A * A + (1 - alpha_A * B). But in this formula we're working with floating point values and alpha is a value between 0 and 1.

Since we're working with integer values the alpha (and red, green and blue as well) is a value between 0 and 255. So the value of 1 - alpha_A is encapsulated in inv_alpha_A = 255 - alpha_A.

Since each color may not exceed the maximum value of one byte we have to ensure that the calculated number does not exceed 255. So we have to divide by 255.This results in:

C = (alpha_A * A + inv_aplha_A * B) / 255

(I intentionally skipped the rounding problem).

gmug
  • 773
  • 5
  • 11