12 unique colors in PNG -- extract to 12 different PNGs

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
pipitas
Posts: 168
Joined: 2012-07-15T14:06:46-07:00
Authentication code: 15

12 unique colors in PNG -- extract to 12 different PNGs

Post by pipitas »

I have a PNG with only 12 unique colors.

I'm looking for a efficient and fast method to convert this to 12 different PNGs where each resulting image keeps all pixels of one of the respective unique colors, while converting all the others to transparent pixels.

So far I've come up only with a very slow one (which I could script easily too):
  1. Determine the exact color values of the 12 unique colors. I could use convert my.png text:- | sort | uniq -c .
  2. Determine one pixel in the PNG which uses this exact color. I could use convert my.png text:- | grep ${color1} | head -n 1.
  3. Color-convert all pixels which match 11 other colors to transparent. I could use 12 variants of convert my.png -alpha on -fill none -draw 'color X2,Y2 replace' -draw 'color X3,Y3 replace' -draw [....] -draw 'color X12,Y12 replace' my-output-color1.png
However, while this method should work (I've only tried it for changing 2 single colos out of the 12 into transparent, not 11 out of 12), I do not want to follow that road.

There must be a better, faster method -- one that can do the whole operation in a single command line, preferably.

Here is the list of unique color values in my PNG:

Code: Select all

#10110C
#374344
#463A2B
#544A35
#605E57
#6F7D7C
#857A6B
#947113
#98926D
#A69E95
#BBC0A7
#F3EEE6
Here is the list of 12 different pixels using these values:

Code: Select all

0,0
264,0
457,0
575,4
279,0
283,0
394,5
594,24
577,1
390,0
391,0
395,4
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by fmw42 »

Post your image to dropbox.com and put the URL here.

I think there are more efficient ways to do this. I do not think you need coordinates. You can use IM -unique-colors to get the colors and list them to an array or list. You can loop over the array (or list colors) and use -fill none +opaque onecolor to make all 11 other colors transparent. You probably can do this in one command line writing out each of the results to a new file using -write.

If I misunderstand what you are trying to do, please clarify. But it seems you want one image output for each color, showing that color only and the rest transparent.

Also always provide your version of IM and platform. Syntax may be different.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by fmw42 »

Here is kind of a simple example where I have appended the six primary and secondary colors together as 100x100 swatches for the input image. The output is six image showing one color in each and the rest transparent.

Unix syntax

Code: Select all

convert -size 100x100 xc:red xc:green1 xc:blue xc:magenta xc:yellow xc:cyan +append colors.gif
colorlist=`convert colors.gif -unique-colors txt: | tail -n +2 | sed 's/[ ][ ]*/ /g' | cut -d\  -f4`
string=""
for color in $colorlist; do
string="$string \( -clone 0 -fill none +opaque $color +write ${color}.gif \)"
done
eval convert -respect-parenthesis colors.gif -channel rgba "$string" null:
The eval is needed to make the command line recognize the escaped parentheses in the $string.
pipitas
Posts: 168
Joined: 2012-07-15T14:06:46-07:00
Authentication code: 15

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by pipitas »

fmw42 wrote:Post your image to dropbox.com and put the URL here.
http://i.stack.imgur.com/Xots0.png

Image

fmw42 wrote:I think there are more efficient ways to do this.
Yes, that's why I'm asking :D
fmw42 wrote:If I misunderstand what you are trying to do, please clarify. But it seems you want one image output for each color, showing that color only and the rest transparent.
Yes, exactly.
fmw42 wrote:Also always provide your version of IM and platform. Syntax may be different.
My ImageMagick runs on OSX Mavericks and is this version:

Code: Select all

Version: ImageMagick 6.9.0-0 Q16 x86_64 2014-12-06 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules
Delegates (built-in): bzlib cairo djvu fftw fontconfig freetype gslib gvc jbig jng jp2 jpeg lcms lqr ltdl lzma openexr
                      pangocairo png ps rsvg tiff webp wmf x xml zlib
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by fmw42 »

You have 15 unique colors not 12. Nevertheless, my code should work.

Code: Select all

convert Xots0.png -unique-colors txt:
# ImageMagick pixel enumeration: 15,1,255,srgb
0,0: (34,31,32)  #221F20  srgb(34,31,32)
1,0: (85,45,42)  #552D2A  srgb(85,45,42)
2,0: (67,67,69)  #434345  srgb(67,67,69)
3,0: (98,94,90)  #625E5A  srgb(98,94,90)
4,0: (172,57,57)  #AC3939  srgb(172,57,57)
5,0: (150,105,99)  #966963  srgb(150,105,99)
6,0: (111,149,99)  #6F9563  srgb(111,149,99)
7,0: (152,142,114)  #988E72  srgb(152,142,114)
8,0: (223,194,85)  #DFC255  srgb(223,194,85)
9,0: (73,101,162)  #4965A2  srgb(73,101,162)
10,0: (75,146,191)  #4B92BF  srgb(75,146,191)
11,0: (167,161,153)  #A7A199  srgb(167,161,153)
12,0: (201,180,167)  #C9B4A7  srgb(201,180,167)
13,0: (201,201,181)  #C9C9B5  srgb(201,201,181)
14,0: (230,230,226)  #E6E6E2  srgb(230,230,226)
pipitas
Posts: 168
Joined: 2012-07-15T14:06:46-07:00
Authentication code: 15

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by pipitas »

fmw42 wrote:You have 15 unique colors not 12.
Sorry, yes. Wanted to hint at the fact, but forgot. Had to use a different image.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by fmw42 »

My code needs a modification to get the hex (or rgb) colors. So rather than using the last column of color values that can be names or rgb values, I switched it to get consistent hex values from the third column and one other modification, since those colors need quoting. This works on the image you provided.

Code: Select all

infile="Xots0.png"
inname=`convert "$infile" -format "%t" info:`
echo "$inname"
colorlist=`convert "$infile" -unique-colors txt: | tail -n +2 | sed 's/[ ][ ]*/ /g' | cut -d\  -f3`
echo "$colorlist"
string=""
for color in $colorlist; do
color="\"$color\""
string="$string \( -clone 0 -fill none +opaque $color +write ${inname}_${color}.gif +delete \)"
done
eval convert -respect-parenthesis "$infile" -channel rgba "$string" null:

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

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by snibgo »

Using IM at the command level, I can't see a quicker method than Fred's. After each gif is created, that image can be deleted from the list, saving some memory.

That method scans the input image for each colour (in each "+opaque" operation). A custom program or process module could, instead, first build all the new transparent images. Then it scans the input once. Each pixel found is copied to the appropriate output image.

This should be slightly faster. But not much. It wouldn't save any disk I/O, merely each scan of the in-memory image.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by fmw42 »

snibgo wrote:After each gif is created, that image can be deleted from the list, saving some memory.
Good thought! I have modified my script to include +delete
pipitas
Posts: 168
Joined: 2012-07-15T14:06:46-07:00
Authentication code: 15

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by pipitas »

fmw42 wrote:My code needs a modification to get the hex (or rgb) colors. So rather than using the last column of color values that can be names or rgb values, I switched it to get consistent hex values from the third column and one other modification, since those colors need quoting.
That (switching to third column instead of last one) I have done already, independently from your last modification. My reason was also the consistency feature (to always get hex values instead of colornames or srgb values, plus: the parentheses of "srgb(x,y,z)" gave me problems because they were un-escaped.

In any case: thank you very much (also to snibgo) for your support and your invaluable input.
MrBraddock
Posts: 1
Joined: 2016-05-16T03:59:29-07:00
Authentication code: 1151

Re: 12 unique colors in PNG -- extract to 12 different PNGs

Post by MrBraddock »

How exactly do I run this in Windows? Do I needs to create a script file and somehow append it to a command line? Sorry, I am really new to this.
Post Reply