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

Magick++ is an object-oriented C++ interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick++.
Post Reply
jsanterre
Posts: 31
Joined: 2014-05-09T10:39:21-07:00
Authentication code: 6789

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

Post 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
drunkensapo
Posts: 23
Joined: 2013-08-14T15:40:56-07:00
Authentication code: 6789

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

Post by drunkensapo »

Did you have any luck with this? I'm having a lot of trouble with alpha channels and PNG images.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

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

Post 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.
snibgo's IM pages: im.snibgo.com
Post Reply