Pick a color and use it in a IM command

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
roipoussiere
Posts: 9
Joined: 2016-08-02T03:02:48-07:00
Authentication code: 1151

Pick a color and use it in a IM command

Post by roipoussiere »

As explained in a previous post, I extracted a mask from a photo:

Code: Select all

convert original.jpg -fuzz 25% -fill None -floodfill +0+0 '#0a613e' -alpha extract -morphology Open Disk mask.png
Note here I use the color #0a613e, which I picked using Gimp.

Now I would like to automatically detect the background color to make my script more reusable. :-)

For that I get the average color of the borders.

First, here is how I get the color for the 200px north border:

Code: Select all

original.jpg -gravity North -crop 0x200+0+0 -resize 1x1 color.png
It results a 1x1 pixel image, with the average color of this border (because -resize 1x1 take the average color, thanks SO).

Now, the code for all borders of the image is:

Code: Select all

convert \( original.jpg -gravity North -crop 0x200+0+0 -resize 1x1 \) \( original.jpg -gravity South -crop 0x200+0+0 -resize 1x1 \) \( original.jpg -gravity East -crop 200x0+0+0 -resize 1x1 \) \( original.jpg -gravity West -crop 200x0+0+0 -resize 1x1 \) +append -resize 1x1 color.png
Well! Now how to set the color of my pixel in a ImageMagick command, to replace '#0a613e' above? :-P
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pick a color and use it in a IM command

Post by fmw42 »

What is your IM version and platform? Syntax differs.

In Unix:

Code: Select all

color=$(convert \( original.jpg -gravity North -crop 0x200+0+0 -resize 1x1 \) \( original.jpg -gravity South -crop 0x200+0+0 -resize 1x1 \) \( original.jpg -gravity East -crop 200x0+0+0 -resize 1x1 \) \( original.jpg -gravity West -crop 200x0+0+0 -resize 1x1 \) +append -resize 1x1 -format "%[pixel:u.p{0,0}]" info:)
So now use $color where you want to specify the background color.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pick a color and use it in a IM command

Post by fmw42 »

You could also do

Code: Select all

convert \( original.jpg -gravity North -crop 0x200+0+0 -resize 1x1 \) \( original.jpg -gravity South -crop 0x200+0+0 -resize 1x1 \) \( original.jpg -gravity East -crop 200x0+0+0 -resize 1x1 \) \( original.jpg -gravity West -crop 200x0+0+0 -resize 1x1 \) +append -resize 1x1 -scale WxH \( original.jpg -fuzz XX% -trim +repage \) +swap -compose over -composite result.png
where WxH is the size of your original.jpg. Thus the trimmed original is put over the solid average color background.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Pick a color and use it in a IM command

Post by snibgo »

roipoussiere wrote:... because -resize 1x1 take the average color ...
It does, but "-scale 1x1!" also does, and is quicker.
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: Pick a color and use it in a IM command

Post by fmw42 »

You can replace your textured background with the average background color fully around by getting the size of the original. Then creating an image the size of the original of the average color. Then use the mask to composite the two together.

Original:
Image

IM 6 (two convert commands)

Code: Select all

size=$(convert original.png -format "%wx%h" info:)
convert original.png +write mpr:img \
\( mpr:img -fuzz 25% -fill None -floodfill +0+0 '#0a613e' \
-alpha extract -morphology Open Disk -negate +write mpr:mask \
mpr:img +swap -alpha off -compose copy_opacity -composite \
-scale 1x1! -alpha off -scale $size! \) \
mpr:mask -compose over -composite result1.png
Image


IM 7 (one convert command)

Code: Select all

convert original.png -set option:size "%wx%h" +write mpr:img \
\( mpr:img -fuzz 25% -fill None -floodfill +0+0 '#0a613e' \
-alpha extract -morphology Open Disk -negate +write mpr:mask \
mpr:img +swap -alpha off -compose copy_opacity -composite \
-scale 1x1! -alpha off -scale $size! \) \
mpr:mask -compose over -composite result2.png
Image
roipoussiere
Posts: 9
Joined: 2016-08-02T03:02:48-07:00
Authentication code: 1151

Re: Pick a color and use it in a IM command

Post by roipoussiere »

What is your IM version and platform? Syntax differs.
Ubuntu, IM v6.8.9

Thanks a lot for your responses!

I think I prefer the version with $color. :-)
It does, but "-scale 1x1!" also does, and is quicker.
Ok!

Just an other related question:

You used -format "%[pixel:u.p{0,0}]" info:) to format the output.
I currently work with compare -subimage-search (see other topic), which outputs something like 12824.3 (0.195686) @ 28,12. Is it possible to format this output in order to use with an other command, like this one below (Perspective Distortion example)?

Code: Select all

convert building.jpg -matte -virtual-pixel transparent -distort Perspective '7,40 4,30   4,124 4,123   85,122 100,123   85,2 100,30' building_pers.png
Or I need to parse the output with a script?

Edit: Just saw your last response, thanks! But you used '#0a613e', however I don't want to specify the color manually, that's why I deal with average border color.
Last edited by roipoussiere on 2016-08-02T16:03:23-07:00, edited 1 time in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Pick a color and use it in a IM command

Post by fmw42 »

-format "%[pixel:u.p{0,0}]" info:
This only works with convert or identify, as far as I know. But you can do compare as a convert ... -compare command.

see http://www.imagemagick.org/script/comma ... hp#compare. I am not sure if it allows -subimage-search.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Pick a color and use it in a IM command

Post by snibgo »

To find the background colour, a useful method is to take all the pixels around the edge of the image (or just some of the edges). For just those pixels, find the minimum and maximum values in each channel. From the min and max values, calculate the middle values, and the smallest fuzz value that encompasses all the edge pixels.

fuzz = sqrt ((range_red^2 + range_green^2 + range_blue^2)/3

Then we can "-floodfill" from (0,0) with the given middle colour and fuzz.

For this "tango" image, we have:

Code: Select all

tango_FUZZ=24.6178%
tango_MID=sRGB(5.29412%,28.8235%,18.6275%)
EDIT: Added the divide by 3.
snibgo's IM pages: im.snibgo.com
roipoussiere
Posts: 9
Joined: 2016-08-02T03:02:48-07:00
Authentication code: 1151

Re: Pick a color and use it in a IM command

Post by roipoussiere »

Well, sorry I think this is beyound my knowledge in image processing...

A working example could help me, how did you get tango_FUZZ and tango_MID?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Pick a color and use it in a IM command

Post by snibgo »

I explained it in the first paragraph. For example, of the edge pixels, I found the minima and maxima red values. The average of those two was 5.29% of quantum.
snibgo's IM pages: im.snibgo.com
roipoussiere
Posts: 9
Joined: 2016-08-02T03:02:48-07:00
Authentication code: 1151

Re: Pick a color and use it in a IM command

Post by roipoussiere »

For example, of the edge pixels, I found the minima and maxima red values.
Ok, but did you do that with IM or with an other language?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Pick a color and use it in a IM command

Post by snibgo »

With IM. For example, "%[fx:50*(maxima.r+minima.r)]" gives the mean value in the Red channel, on a scale of 0.0 to 100.0. "%[fx:maxima.r-minima.r]" gives the range in the Red channel, on the scale 0.0 to 1.0.
snibgo's IM pages: im.snibgo.com
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Pick a color and use it in a IM command

Post by snibgo »

I've uploaded a "Subimage rectangles" page, with section "Middle and fuzz of edge pixels" that gives the details.
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: Pick a color and use it in a IM command

Post by fmw42 »

In IM 7, you can do this to get the average color of some subsection and use it in the same command to add a border or exend the image:

Code: Select all

im7 magick rose: -write mpr:img \
\( mpr:img -gravity center -crop 20x20+0+0 +repage -scale 1x1! \
	-set option:color "%[pixel:u.p{0,0}]" +delete \) \
-gravity center -background "%[color]" -extent 100x100 rose_color.jpg
or this

Code: Select all

magick rose: \
\( -clone 0 -gravity center -crop 20x20+0+0 +repage -scale 1x1! \
	-set option:color "%[pixel:u.p{0,0}]" +delete \) \
-gravity center -background "%[color]" -extent 100x100 rose_color.jpg

Image
Post Reply