Page 1 of 1

Unable to detect the alpha channel in a PNG image file (without loading the entire image in memory)

Posted: 2015-09-08T07:57:30-07:00
by jsanterre
Hi,

I'm using Magick++ to read/write images from/to files (version 6.9.1-4) and everything is working fine.

Now, I need to "ping" the file to get basic information about an image file without reading/loading all the image pixels. I simply need to read the file headers. I know there's a ping function I can use in Magick::Image that gives the image columns, rows, and filesize (as stated in the doc). Unfortunately, I need more than that. In particular, I need to know the image compression, pixel bit depth and I need to know if the image has an alpha channel.

Then I tried the function PingImage in MagickCore::Image that is supposed to give all the information I would need (as stated in the doc). It turns out that the ping function in Magick::Image can also give that information too! So I'm now getting all the information I need either by using Magick::Image::ping() or MagickCore::PingImage() for almost every file format. The one exception is the matte property for PNG files.

Here's a test PNG image having an alpha channel:
https://www.dropbox.com/s/4ecimzvd7s8zn ... 6.png?dl=0

Trying the following:

Code: Select all

std::string filename = //path//to//test png image
MagickCore::ImageInfo* imageInfo;
MagickCore::ExceptionInfo *exception;
exception = MagickCore::AcquireExceptionInfo();
imageInfo = MagickCore::CloneImageInfo( ( MagickCore::ImageInfo *) NULL );
( void ) strcpy( imageInfo->filename, filename.c_str() );
MagickCore::Image* image = MagickCore::PingImage( imageInfo, exception );
std::cout << image->matte << std::endl;
will print the value 0, even if the test image has an alpha channel.

On the other hand, trying the following:

Code: Select all

std::string filename = //path//to//test png image
MagickCore::ImageInfo* imageInfo;
MagickCore::ExceptionInfo *exception;
exception = MagickCore::AcquireExceptionInfo();
imageInfo = MagickCore::CloneImageInfo( ( MagickCore::ImageInfo *) NULL );
( void ) strcpy( imageInfo->filename, filename.c_str() );
MagickCore::Image* image = MagickCore::ReadImage( imageInfo, exception );
std::cout << image->matte << std::endl;
or a lot more simply, trying the following:

Code: Select all

std::string filename = //path//to//test png image
Magick::Image m_image;
image.read( filename );
std::cout << image.matte() << std::endl;
will correctly print the value 1.

Note that I get the correct results when testing GIF and TIF image files. I can also get the correct results for compression and bit depth for PNG image files. How come I get wrong results for detecting an alpha channel in a PNG files? Is it possible there's a bug for the PNG format? If the answer is yes, is there a workaround that I could use to detect if a PNG image file has an alpha channel without reading the entire image in memory? Is there another function/property attached to either a Magick::Image or a MagickCore::Image that would detect the alpha channel without reading the pixels in memory?

Thank you very much for any help I can get to help me solving this issue. I really appreciate it!

Julie

Re: Unable to detect the alpha channel in a PNG image file (without loading the entire image in memory)

Posted: 2016-06-03T11:26:04-07:00
by drunkensapo
Did you have any luck with this? I'm having a lot of trouble with alpha channels and PNG images.

Re: Unable to detect the alpha channel in a PNG image file (without loading the entire image in memory)

Posted: 2016-06-03T13:17:59-07:00
by snibgo
I've never used PingImage() etc, but it seems that:

1. image->matte refers to whether the pixels contain any transparency. Thus its value has no significance until the pixels are read.

2. "ping on a PNG doesn't read the pixels, so image->matte means nothing.

3. "ping" on a TIFF image actually reads the pixels.