Thanks
Thanks

Reputation: 40349

How can I add the alpha channel of image A to the alpha channel of image B?

I have two images. One of them is just plain white and has some areas with alpha transparency. It is intended to be a mask for making another image transparent. The other image, full colored and also PNG, has no alpha applied anywhere.

So I want to add the alpha values of the mask image to the alpha values of the other. Both images have the exact same size. It would be just a matter of looping through the pixels, I guess. Any idea how that would look in detail?

Upvotes: 2

Views: 1651

Answers (4)

Mayosse
Mayosse

Reputation: 696

CGImageRef resultImage = CGImageCreateWithMask([imageA CGImage],[imageB CGImage]); UIImage* img= [UIImage imageWithCGImage:resultImage]; CGImageRelease(resultImage); return img;

Upvotes: 1

Wil Shipley
Wil Shipley

Reputation: 9553

"clemahieu" is right -- You don't have to worry about premultiplied alpha in this case, because you're doing high-level operations, and the actual pixel format is a low-level detail.

If you simply composite the white/alpha image over the color/no alpha image (in a color/alpha buffer) using the correct compositing operator, you'll get exactly what you want.

-Wil

Upvotes: 1

Mark
Mark

Reputation: 6128

The quickest way I can think of is to get a pointer to the buffer for each image and combine them in a third buffer looping through all of the pixels, like you mentioned.

Or if the source (color) image has an alpha channel, but it is set to 1 just replace that channel with the alpha from the second image.

Starting in Panther Quartz has an alpha only bitmap context that can be used to mask other images. The excellent book programming with quartz 2d and pdf graphics in mac os x has a section on alpha only bitmap contexts.

To get the alpha from a crunched PNG file you can do something similar to the following:


    CGImageRef myImage = [self CGImage];
    CGSize newSize = {CGImageGetWidth(myImage), CGImageGetHeight(myImage)};

if(!isPowerOf2(newSize.width))
    newSize.width = nextPowerOf2(newSize.width);
if(!isPowerOf2(newSize.height))
    newSize.height = nextPowerOf2(newSize.height);


const GLint picSize = newSize.height * newSize.width * 4;

// The bitmapinfo provided by the CGImageRef isn't supported by the bitmap context.
// So I'll make a conforming bitmap info
CGBitmapInfo myInfo = kCGImageAlphaPremultipliedLast;

unsigned char * actual_bytes = new unsigned char[picSize];
CGContextRef imageContext = CGBitmapContextCreate(
                                                  actual_bytes,
                                                  newSize.width,
                                                  newSize.height,
                                                  CGImageGetBitsPerComponent(myImage),
                                                  newSize.width * 4,
                                                  CGImageGetColorSpace(myImage),
                                                  myInfo);

CGContextSaveGState(imageContext);
CGContextDrawImage(imageContext, [self bounds], myImage);
CGContextRestoreGState(imageContext);

At this point actual_bytes has the RGBA data. Don't forget to delete the memory for actual_bytes. This is a category on UIImage so self is a UIImage that has already been loaded from a PNG file.

Upvotes: 0

clemahieu
clemahieu

Reputation: 1429

Check out Alpha compositing. http://en.wikipedia.org/wiki/Alpha_compositing It looks like you're trying to perform A out B.

Upvotes: 1

Related Questions