c++ - Pixels Overlay With transparency -


i have 2 pixels in b8g8r8a8 (32) format. both pixels (top , bottom) has transparency (alpha channel < 255 )

what way (formula) overlay top pixel on bottom 1 ? (without using 3rd parties).

i tried this

struct fcolor { public:     // variables. #if platform_little_endian     #ifdef _msc_ver         // win32 x86         union { struct{ uint8 b,g,r,a; }; uint32 alignmentdummy; };     #else         // linux x86, etc         uint8 b gcc_align(4);         uint8 g,r,a;     #endif #else // platform_little_endian     union { struct{ uint8 a,r,g,b; }; uint32 alignmentdummy; }; #endif //... };  forceinline fcolor alphablendcolors(fcolor pixel1, fcolor pixel2) {     fcolor blendedcolor;     //calculate new alpha:     uint8 newalpha = 0;     newalpha = pixel1.a + pixel2.a * (255 - pixel1.a);      //get fcolor uint32     uint32 colora = pixel1.dwcolor();     uint32 colorb = pixel2.dwcolor();      uint32 rb1 = ((0x100 - newalpha) * (colora & 0xff00ff)) >> 8;     uint32 rb2 = (newalpha * (colorb & 0xff00ff)) >> 8;     uint32 g1 = ((0x100 - newalpha) * (colora & 0x00ff00)) >> 8;     uint32 g2 = (newalpha * (colorb & 0x00ff00)) >> 8;     blendedcolor = fcolor(((rb1 | rb2) & 0xff00ff) + ((g1 | g2) & 0x00ff00));       blendedcolor.a = newalpha;     return blendedcolor; } 

but result far not want :-)

i looked alpha blending formulas (i did never understand how calculate new alpha of overlay) -> perhaps going in wrong direction ?

edit:

changing newalpha newalpha = fmath::min(pixel1.a + pixel2.a, 255); gives better result, right calculate ? missing here?

working example based on accepted answer)

   forceinline fcolor alphablendcolors(fcolor bottompixel, fcolor toppixel) {     fcolor blendedcolor;     //calculate new alpha:     float norma1 = 0.003921568627451f * (toppixel.a);     float norma2 = 0.003921568627451f * (bottompixel.a);      uint8 newalpha = (uint8)((norma1 + norma2 * (1.0f - norma1)) * 255.0f);      if (newalpha == 0)     {         return fcolor(0,0,0,0);     }      //going straight alpha formula     float dstcoef = norma2 * (1.0f - norma1);     float multiplier = 255.0f / float(newalpha);      blendedcolor.r = (uint8)((toppixel.r * norma1 + bottompixel.r * dstcoef) * multiplier);     blendedcolor.g = (uint8)((toppixel.g * norma1 + bottompixel.g * dstcoef) * multiplier);     blendedcolor.b = (uint8)((toppixel.b * norma1 + bottompixel.b * dstcoef) * multiplier);      blendedcolor.a = newalpha;      return blendedcolor; } 

start assuming there third pixel below happens opaque.

for further notations, assume alpha values in [0,1].

given: 3 pixels first 1 being on top, colors c_1, c_2, c_3, alpha values a_1, a_2, a_3 = 1

then resulting alpha value 1 , color is

(a_1)*c_1 + (1-a_1)(*a_2)*c_2 + (1-a_1)*(1-a_2)*c_3 

now, want find values c_k, a_k formula above equates

(a_k)*c_k + (1-a_k)*c_3 

we can solve in 2 steps:

(1-a_k) = (1-a_1)*(1-a_2) -> a_k = 1-(1-a_1)*(1-a_2) 

and

(a_k)*c_k = (a_1)*c_1 + (1-a_1)(*a_2)*c_2 -> c_k = [(a_1)*c_1 + (1-a_1)(*a_2)*c_2] / a_k 

use formulas (with different range alpha values) , desired color.

(don't forget catch a_k = 0)

edit: explanation of third pixel:

when use 2 pixels in way, doing results in being used display something, put on other existing color opaque. example, might background color, color result of applying many more transparent pixels on background color.

what combine 2 colors find color behaves 2 colors. is, putting on top of opaque color should result in same putting original 2 colors on top of it. demand of new color, resulting in formula use.

the formula nothing result of applying 2 colors in succession on third one.


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -