QueryColor()

PerlMagick is an object-oriented Perl interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning PerlMagick.
Post Reply
User avatar
rmabry
Posts: 148
Joined: 2004-04-13T11:25:27-07:00

QueryColor()

Post by rmabry » 2018-02-03T14:30:33-07:00

In the Miscellaneous Methods section of the PerlMagick doc is this:
Call QueryColor() with no parameters to return a list of known colors names or specify one or more color names to get these attributes: red, green, blue, and opacity value.

@colors = $image->QueryColor();
($red, $green, $blue, $opacity) = $image->QueryColor('cyan');
($red, $green, $blue, $opacity) = $image->QueryColor('#716bae');
The above suggest four elements are returned, but when I try it (on ImageMagick 7.0.7-15 Q16 x86_64 2018-01-17, Centos 6.9, perl v5.10.1), I get an error with those last two calls, i.e., when asking for four elements:

Code: Select all

printf("red = %d, green = %d, blue = %d, opacity = %d\n", $red, $green, $blue, $opacity);
Use of uninitialized value $opacity in printf at ___.plx line __
With the following, scalar(@colors) returns 3:

Code: Select all

@colors = $image->QueryColor("red");
If it is passed #ffaa8833, then @colors does get 4 elements.

Also, if I give it an unknown color, I don't get an empty array, at least not exactly. I get an array with one element (according to scalar(@colors)), for example with this:

Code: Select all

@colors = $image->QueryColor("tanfastic");
But that one element is not defined! I expected an empty array, i.e., one with zero elements, which makes the testing a bit more convenient, or so I'd think. One undefined element seems pretty weird, but what do I know? I can deal with it, but it ought to be mentioned in the doc.

Another surprise was that the returned results are integers. Calling QueryColor on any of #ff8800, #ffff88880000, or #ffffffff8888888800000000 returns the array (65535, 34952, 0). I'd expected a normalized result. Or perhaps the integers make more sense, depending on the image?

But I notice that it doesn't seem dependent on that, since the following works:

Code: Select all

@colors = Image::Magick->QueryColor("red");
That actually makes more sense to me, since the colors seem more like constants than image-dependent quantities.

Either way, it would be cool to be able to ask for the format, perhaps like so:

Code: Select all

@colors = $image->QueryColor("red", format => 'real');
Rick

snibgo
Posts: 10716
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: QueryColor()

Post by snibgo » 2018-02-04T05:32:11-07:00

The only part of your query that I can address is:
rmabry wrote:Another surprise was that the returned results are integers. Calling QueryColor on any of #ff8800, #ffff88880000, or #ffffffff8888888800000000 returns the array (65535, 34952, 0). I'd expected a normalized result. Or perhaps the integers make more sense, depending on the image?
Values generally are normalized, but to QuantumRange.

Named colours are defined in color.c. They are defined as RGBA components, where RGB are integers 0 to 255, and alpha is floating-point. Almost all named colours have alpha=1. The colours "none" and "transparent" have alpha=0.

As a general rule, IM reports colour channel values on a scale of 0 to QuantumRange inclusive, where QuantumRange=(2^Q)-1 where Q is 8, 16, 32 or 64, so QuantumRange is 255, or 65535, etc.
snibgo's IM pages: im.snibgo.com

User avatar
rmabry
Posts: 148
Joined: 2004-04-13T11:25:27-07:00

Re: QueryColor()

Post by rmabry » 2018-02-04T10:45:40-07:00

snibgo wrote:
2018-02-04T05:32:11-07:00
Named colours are defined in color.c. They are defined as RGBA components, where RGB are integers 0 to 255, and alpha is floating-point. Almost all named colours have alpha=1. The colours "none" and "transparent" have alpha=0.
Something like you describe (an alpha component for each color even if it is 100%) would be expected when one looks at the PerlMagick doc, as I quoted it. But aside from the two you mentioned ("none", "transparent") and two more ("freeze", "matte"), all four of which produce the 4-component array (0,0,0,0), all the other colors in the list produce just 3 components when fed to QueryColor(). Here's a one-line shell command that spews them all out, assuming the installation of PerlMagick (and perl); it can be grep'd for "4 components":

Code: Select all

perl -MImage::Magick -le 'map printf("%s gives %d components\n", $_, scalar(@x=Image::Magick->QueryColor($_))), Image::Magick->QueryColor()'
My main point was simply that the doc is wrong as stated, but I do also think a few enhancements would be nice, including the ability to easily get a desired formatting, as some other commands have. And better handling of unknown color names, which I think is more important.

Rick

Post Reply