How implement alfa channel

I want to implement a 32 bit bitmap with alfa channel in an arm7 micro....the function is new_pixel=alfa*pixel_foreground+(1-alfa)*pixel_background alfa is an 8 bit value from zero to one (from zero to 255). This function can be done in this way:

1)float cast of alfa and pixel_foreground 2)alfa1=alfa/255 3)new_value1=alfa1*pixel_foreground 3)new_pixel=new_value1+new_value2 3)int cast af new_pixel This procedure is time consuming and very difficult without mathematical coprocessor...any better way? Thanks
Reply to
doc.bullwinkle
Loading thread data ...

Don't use floating point, rearrange the formula so you can use integer arithmetic.

Reply to
Dombo

Try this code. It rounds different than your approach because that makes it cheaper to avoid the division by 255, but it's a lot faster.

unsigned int blend_argb32 (unsigned int a, unsigned int b, ui8 delta) { unsigned int dstrb = a & 0xFF00FF; unsigned int dstag = a >> 8 & 0xFF00FF; unsigned int srcrb = b & 0xFF00FF; unsigned int srcag = b >> 8 & 0xFF00FF; unsigned int drb = ((srcrb - dstrb) * delta)>>8; unsigned int dag = ((srcag - dstag) * delta)>>8; a = (drb + dstrb) & 0x00FF00FF; b = (dag + dstag)

Reply to
Nils

If you are representing data as integers there's really no need to convert to floating point to do this. Doing so will rob you of a lot of performance:

pixel = (alpha * foreground + (255 - alpha) * background + 128) / 255;

For most purposes you can drop the + 128. That is only really needed if you are being pedantic - it ensures the division is rounded properly. If the output is a screen you can drop that for a slight speed improvement and you will never notice the difference. It may be needed if the result is used as a further basis for calculation though.

--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply to
Andrew Smallshaw

That divide by 255 can cost you as much time as the rest of the math on that line, make it 256 like everyone else does and double your speed. pixel = ((alpha * foreground + (255 - alpha) * background)) >> 7; You may also need clamping for results not in range of 0-255.

Reply to
Brett Davis

Nah - nowadays all compilers know that division by 2^N, 2^N-1 and 2^N+1 are cheap to calculate. In the case of 255 it becomes:

int DivideBy255 (int a) { return ((a>>8) + a + 1)>>8; }

It could be off one bit if a is negative (haven't checked), but for positive integers it gives identical results.

And before the c-standard nazi chimes in: I assume that signed shifts replicate the sign-bits *and* that a range-propagation pass has made sure that no overflow is possible. This is guaranteed in the case of 8 bit integers.

Reply to
Nils

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.