Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accurately Convert from Straight Alpha to Premultiplied Alpha and Back

I have an RGBA source image that I need to convert to Pre-Multiplied BGRA for use in WPF image display and scaling. Afterwards I need to convert the PBGRA back into straight RGBA. I've been using these formulae to convert and convert back:

PC = C * A / 255.0 + 0.5

and back:

C = 255.0 * PC / A + 0.5

where C is Color and PC is Pre-Multiplied Color and both are of type byte.

The problem is that this is producing a lot of off-by-one errors when I do nothing but convert the RGBA to PBGRA and back to RGBA with no further processing and then comparing the original RGBA with the resulting converted RGBA.

Is there a convert-to and convert-back set of algorithms that will produce an exact copy of the original image?

I am working with C# but any examples with C/C++ or Java would work.

This is the code I use to pre-multiply:

Func<byte, byte, byte> preMultiply = (source, alpha) => (byte)(source * (double)alpha / 255.0 + 0.5);

And to convert back:

Func<byte, byte, byte> deMultiply = (color, alpha) => {
    if (alpha == 0) return color;

    return (byte)(255.0 * color / alpha + 0.5);
};

Is there any way to do that is "less" lossy?

like image 738
stricq Avatar asked Aug 31 '25 20:08

stricq


1 Answers

Unfortunately not, this conversion generates irreversible information loss.

To understand why, let A=128. Then all C values in the range [0,255] will map to [0,127]. Obviously, one bit is lost forever.

With A=0, you lose... all the bits.