Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 801
RunLoop Avatar asked Apr 13 '13 08:04

RunLoop


People also ask

How do you check the transparency of an image?

Images that have transparency often illustrate it by using a gray and white checkered pattern. The idea is that you can see which parts of the image will be transparent before you save it. The checkered pattern is the background. There's no transparency.

How do you know if a JPEG is transparent?

Just right-click on the image and check the properties. If the formate is PNG then the background is transparent, and if the image format is JPEG then it's not transparent.

What is transparency in images?

In digital photography, transparency is the functionality that supports transparent areas in an image or image layer. Certain image formats do not support transparency. Opacity is the extent to which something blocks light.


1 Answers

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.

like image 114
Sten Avatar answered Oct 21 '22 08:10

Sten