BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.25k stars 4.61k forks source link

kCGImageAlphaLast NOT iOS Compatible & Hack #1013

Open drmiller opened 11 years ago

drmiller commented 11 years ago

I capture two images using the ChromaKeyBlend filter (for a filtered image) and Brightness filter (for an "unfiltered" original image) with capturePhotoAsPNGProcessedUpToFilter: for the original and using imageFromCurrentlyProcessedOutputWithOrientation: for the filtered (chromaKey removed) image. I use the filtered image (after some cropping) to draw (on top of other images) like below. But I got the following errors:

Error: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 9680 bytes/row.
Error: CGContextSetBlendMode: invalid context 0x0
Error: CGContextDrawImage: invalid context 0x0
Error: CGContextFlush: invalid context 0x0

On further review, it seems that kCGImageAlphaLast is not compatible with iOS. So, I searched my project and in GPUImageFilter.m, newCGImageFromCurrentlyProcessedOutputWithOrientation: I (without a clue as to what I was doing) simply replaced kCGImageAlphaLast with kCGImageAlphaPremultipliedLast, AND IT ALL WORKS now!

So, I think this is an issue worth looking into???

UIGraphicsBeginImageContextWithOptions(image.size, NO, 1.0);
[image drawInRect:myRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
BradLarson commented 11 years ago

The line of code referring to kCGImageAlphaLast has been in place for over a year, and has been used successfully by many people, so that element has been compatible with iOS so far. It is possible that some combination of devices / OS versions fail with this, though. What OS / device was this on?

Replacing kCGImageAlphaLast with kCGImageAlphaPremultipliedLast on the offending line in GPUImageFilter.m seems like it would work, because I use kCGImageAlphaPremultipliedFirst for the texture cache case. However, I wonder if this would have any adverse effects with images containing translucent contents. I'm not sure that I'm handling premultiplied alphas correctly throughout the framework.

Still, it's a simple change to make and try.

drmiller commented 11 years ago

It's on an iPad 3 (retina) with iOS 6.1.3. The official docs I found said it should be compatible with iOS 2+??? I know MUCH less about handling premultiplied alphas than you (whatever premultiplied alphas are ;).

It seems to work in all my use cases, and if it doesn't I'll just try to draw it into a non UIKit bitmap context (with kCGImageAlphaPremultipliedLast)???

Note: All these images have translucent areas (where the green was) and are saved as PNGs.