'Detecting transparency in an image
I need to determine whether a png image contains any transparency - what would be the most efficient code to achieve this?
Solution 1:[1]
Convert the PNG image to a pixelbuffer and use vimage to calculate the histograms of the color distributions. Then check the alpha channel histogram. vimage is much faster than going through the pixels one by one.
CVPixelBufferRef pxbuffer = NULL;
vImagePixelCount histogramA[256];
vImagePixelCount histogramR[256];
vImagePixelCount histogramG[256];
vImagePixelCount histogramB[256];
vImagePixelCount *histogram[4];
histogram[0] = histogramA;
histogram[1] = histogramR;
histogram[2] = histogramG;
histogram[3] = histogramB;
vImage_Buffer vbuff;
vbuff.height = CVPixelBufferGetHeight(pxbuffer);
vbuff.width = CVPixelBufferGetWidth(pxbuffer);
vbuff.rowBytes = CVPixelBufferGetBytesPerRow(pxbuffer);
vbuff.data = pxbuffer;
vImage_Error err = vImageHistogramCalculation_ARGB8888 (&vbuff, histogram, 0);
if (err != kvImageNoError) NSLog(@"%ld", err);
int trans = 255 // How little transparency you want to include
BOOL transparent = NO;
for(int i=0; i<trans; i++){
if(histogram[0][i]>0) transparent = YES;
}
vimage assumes that the colors are ordered ARGB in the buffer. If you have something else, e.g. BGRA, you just check histogram[3][i] instead.
Even faster is probably to first split the buffer into four planar buffers using vImageConvert_ARGB8888toPlanar8 and then just do the histogram calculation on the alfa buffer using vImageHistogramCalculation_Planar8.
You can open the PNG image as a CGImage and use vImageBuffer_initWithCGImage to convert it directly to a vimage buffer (see session 703 at WWDC 2014).
Finally, an alternative would be to use Core Image to calculate the histogram.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter Mortensen |