Count number of unique colors minus transparent one

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
redna379
Posts: 25
Joined: 2007-02-22T21:11:40-07:00

Count number of unique colors minus transparent one

Post by redna379 »

Hello,

I have a (perhaps) simple question, but i wasn't able to find a solution yet.
In a script i made, to get the number of unique colors of an image, i'm currently using this command:

Code: Select all

identify +antialias -format "%k" myfile.png
For a pure B/W image with transparent white, the command correctly returns 2.
What i'd need to do is to obtains the number of unique and PRINTABLE colors. In simple terms, i'd need to decrease the returned value by 1 if the image has a fully transparent color in it.

That's it: for a clipart with 102 counted colors, i'd need to obtain 101 if any of those colors is fully transparent.
PRoblem is this has to be done automatically by the script.

Is there anything in ImageMagick to determine if an image is using any fully transparent colors? Or eventually the reverse, IE if all used colors are opaque?

Thanks in advance.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Count number of unique colors minus transparent one

Post by fmw42 »

see %A image alpha channel

and also

%[channels] list of channels (e.g. rgb or rgba etc)

at http://www.imagemagick.org/script/escape.php
redna379
Posts: 25
Joined: 2007-02-22T21:11:40-07:00

Re: Count number of unique colors minus transparent one

Post by redna379 »

fmw42,

Thanks for your reply.
Unfortunately i had already tried those solutions, but with no luck.
Actually, the %A returns true or false: i just don't know if it's about the alpha channel being used, or only about the alpha channel being present.
In any case, it returns TRUE even if i try to identify a png file which has no fully transparent colors, but one or more semi-transparent ones.
Surely that means the alpha channel is in use as the file is an rgba, but such colors are actually visible.

That's the reason of my question about "fully transparent" colors only.
Basically, i'd need to obtain the number of unique visible colors, even if semitransparent.
Or, the opposite way, identify automatically how many colors are fully transparent
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Count number of unique colors minus transparent one

Post by fmw42 »

separate the alpha channel, then threshold it so that black is fully transparent and white is everything else (fully opaque and partially transparent). Multiply that mask with your image and get the number of unique colors. That should include only fully black and then all opaque or partially transparent colors.


convert -size 20x20 xc:red xc:blue xc:"rgba(255,0,0,0.5)" xc:"rgba(0,0,255,0.5)" xc:"rgba(255,0,0,0)" xc:"rgba(0,0,255,0)" +append tmp1_colors.png
Image

convert tmp1_colors.png -format "%k" info:
6

convert tmp1_colors.png \( -clone 0 -alpha extract -threshold 0 \) -compose multiply -composite tmp2_colors.png
Image

convert tmp2_colors.png -format "%k" info:
5

Subtract 1 for the now black color.
Last edited by fmw42 on 2010-05-04T16:10:28-07:00, edited 1 time in total.
redna379
Posts: 25
Joined: 2007-02-22T21:11:40-07:00

Re: Count number of unique colors minus transparent one

Post by redna379 »

Looks interesting and promising!
I will do some tests. Will post again with results ASAP.

Thanks!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Count number of unique colors minus transparent one

Post by fmw42 »

correction to preserve any opaque black. make the new black transparent.

convert tmp1_colors.png \( -clone 0 -alpha extract \) \( -clone 1 -threshold 0 \) \
\( -clone 0 -clone 2 -alpha off -compose multiply -composite \) \
-alpha off -delete 0,2 +swap -compose copy_opacity -composite tmp3_colors.png
Image

convert tmp3_colors.png -format "%k" info:
5

Subtract one for the new transparent black.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Count number of unique colors minus transparent one

Post by anthony »

Be warned that you can have LOTS of semi-transparent colors in an image.

If you are wanting 'printable' colors. I suggest flattening the image to white (paper color)!
then asking how many colors their are.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Count number of unique colors minus transparent one

Post by anthony »

fmw42 wrote:correction to preserve any opaque black. make the new black transparent.

convert tmp1_colors.png \( -clone 0 -alpha extract \) \( -clone 1 -threshold 0 \) \
\( -clone 0 -clone 2 -alpha off -compose multiply -composite \) \
-alpha off -delete 0,2 +swap -compose copy_opacity -composite tmp3_colors.png
Image

convert tmp3_colors.png -format "%k" info:
5

Subtract one for the new transparent black.
I believe that is simply -alpha background
See http://www.imagemagick.org/Usage/basics ... background
this just replaces any fully transparent color with a fully-transparent version of the current background color. It was actually created for use with PNG images to allow them to compress better.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Count number of unique colors minus transparent one

Post by fmw42 »

I believe that is simply -alpha background
Not quite the same as I did and I think he needs as I set all fully transparent pixels to transparent black so that all fully transparent colors no matter what the base color would be counted as one color.

But nice to know about that option anyway.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Count number of unique colors minus transparent one

Post by anthony »

fmw42 wrote:
I believe that is simply -alpha background
Not quite the same as I did and I think he needs as I set all fully transparent pixels to transparent black so that all fully transparent colors no matter what the base color would be counted as one color.

But nice to know about that option anyway.
That is EXACTLY what it does! It just replaces the fully-transparent colors with a single fully-transparent color. Except you can specific the fully-transparent color to use. It does not effect the color of semi-transparent pixels, nor does it 'flatten' the image.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Count number of unique colors minus transparent one

Post by fmw42 »

thanks for the clarification. i misread the docs, just reading the first line that said it maintained the base color. This would have saved me some effort in one other post I had to make earlier. thanks.
redna379
Posts: 25
Joined: 2007-02-22T21:11:40-07:00

Re: Count number of unique colors minus transparent one

Post by redna379 »

Many thanks to Anthony and fmw42 for this interesting discussion!

For various reasons, in my servers i'm forced to use IM version 6.4.4 Q16. So, i can't use the beautyful "-alpha background" option.
However, considering i have to script it, i found a "quick and dirty" way out.

First, i create a temp image by extracting unique colors:
convert image.png -unique-colors temp.png

The resulting temp image preserves also the alpha values.
This image is also extremely handy because, as written in Anthony's guide, it contains just one pixel per unique color found in the original image, all in a single row.
So, at this pont i just have to determine how many of those colors are fully transparent.
To do this in PHP (the language i have to use here), i've used the aid of the GD library.

The function is quite easy, at the end:

Code: Select all

$im = ImageCreateFromPng($tempfile);
$counted_colors=imagesx($im);
for ($i=0; $i<imagesx($im); $i++) {
	$rgb_color_index = imagecolorat($im, $i, 0);
	$rgb_color_tran = imagecolorsforindex($im, $rgb_color_index);
	if ($rgb_color_tran['alpha']==127) $counted_colors--;
}
An finally, i remove the temp image.
As you know, in GD, 127 as alpha channel value means "fully transparent", which is precisely what is needed.
I know it may not sound as the best possible solution, but this way i'm easily able to reduce the colorcount by fully transparent colors using a single operation.

If this may be of any interest for other users, please feel free to comment.
Thanks again!
Post Reply