rbg values of a pixel

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
mfillpot

rbg values of a pixel

Post by mfillpot »

Is it possible to use the imagemagick utilities to extract the rgb values of a specific pixel to be used later by a script?

If so can you please guide me to the correct documentation, I have reviewed several stream and display examples and am currently a little lost.

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

Re: rbg values of a pixel

Post by snibgo »

See the fx documentation: http://www.imagemagick.org/script/fx.php

/usr/bin/convert 7a.png -format 'Pixel is %[fx:p{10,15}]' info:
Pixel is black
/usr/bin/convert 7a.png -format 'Pixel is %[fx:p{10,19}]' info:
Pixel is rgb(18,51,87)
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: rbg values of a pixel

Post by fmw42 »

the easiest way is using fx

convert rose: -format "%[pixel:s.p{10,10}]" info:
rgb(72,64,57)

convert logo: -format "%[pixel:s.p{10,10}]" info:
white

but the pixel: method as you can see will give rgb value or colornames. You cannot control that.

to put it into a variable in unix

pixel10=`convert rose: -format "%[pixel:s.p{10,10}]" info:`
echo "$pixel10"
rgb(72,64,57)


The other way is

convert rose:[1x1+10+10] -format "rgb(%[fx:round(255*u.r)],%[fx:round(255*u.g)],%[fx:round(255*u.b)])" info:
rgb(72,64,57)

or you can get each component separately,

red=`convert rose:[1x1+10+10] -format "%[fx:round(255*u.r)]" info:`
green=`convert rose:[1x1+10+10] -format "%[fx:round(255*u.g)]" info:`
blue==`convert rose:[1x1+10+10] -format "%[fx:round(255*u.b)]" info:`
echo "red=$red; green=$green; blue=$blue"
red=72; green=64; blue==57


see
http://www.imagemagick.org/Usage/transform/#fx_escapes
http://www.imagemagick.org/script/fx.php
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rbg values of a pixel

Post by fmw42 »

snibgo wrote:See the fx documentation: http://www.imagemagick.org/script/fx.php

/usr/bin/convert 7a.png -format 'Pixel is %[fx:p{10,15}]' info:
Pixel is black
/usr/bin/convert 7a.png -format 'Pixel is %[fx:p{10,19}]' info:
Pixel is rgb(18,51,87)

This is not quite correct as using fx:p{x,y} will give results in the range 0-1 as follows (and so must be scaled as in my examples above)

convert rose: -format "%[fx:p{10,19}]" info:
0.372549

perhaps you meant to say pixel: rather than fx:

convert rose: -format "%[pixel:p{10,19}]" info:
rgb(95,75,72)
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rbg values of a pixel

Post by snibgo »

Yes, I meant "pixel". Thanks for the correction. I tried both, then copied/pasted the wrong one.


It's a shame it sometimes returns colour names, so we need a more clumsy format to guarantee values.
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: rbg values of a pixel

Post by fmw42 »

snibgo wrote:Yes, I meant "pixel". Thanks for the correction. I tried both, then copied/pasted the wrong one.
It's a shame it sometimes returns colour names, so we need a more clumsy format to guarantee values.

Yes, I understand. But it is easy to use that format if you want to substitute some color as IM does not care now you specify the color, via name or rgb values.

By the way, it is nice to have another regular contributor, especially as Anthony has been on several months vacation in China. You seem to good grasp of IM for only being on the list for month or so.

Thanks for contributing, snibgo (Alan?).

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

Re: rbg values of a pixel

Post by snibgo »

Ha, you've been snooping! My name is common as muck, so I use an anagram.

I needed to prep 1000 images for the web, and IM seemed the easiest solution. I've been playing with it ever since, like a new toy.

Alan Gibson.
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: rbg values of a pixel

Post by fmw42 »

Got your name from looking at your web site.

Fred
mfillpot

Re: rbg values of a pixel

Post by mfillpot »

Thank you both for the information, this is much more complex that I was thinking, but it is still very cool to know.

I have tried what you recommended with the script below, where XVAL is the x coordinate of the chosen pixel, YVAL1 is the y coordinate of the chosen pixel and ORIGFILE IS THE file name, and I keep getting the same values for all pictures I have run it against.

Code: Select all

# Extract the rgb value for the pixel that the notice starts on
red=`convert $ORIGFILE:[${XVAL}x${YVAL1}+10+10] -format "%[fx:round(255*u.r)]" info:`
green=`convert $ORIGFILE:[${XVAL}x${YVAL1}+10+10] -format "%[fx:round(255*u.g)]" info:`
blue=`convert $ORIGFILE:[${XVAL}x${YVAL1}+10+10] -format "%[fx:round(255*u.b)]" info:`
echo "red=$red; green=$green; blue=$blue"
but I keep getting the errors below:

convert: unable to open image `./0720090921_.jpg:': No such file or directory @ blob.c/OpenBlob/2439.
convert: missing an image filename `info:' @ convert.c/ConvertImageCommand/2775.

I know that those image names are in the directory which the script is being run from.
Can you please tell me what I am doing wrong?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: rbg values of a pixel

Post by snibgo »

(1) The colon (:) is to specify the format, like "rgb:" or "info:", or pseudo-images like "rose:" or "logo:". It's wrong after the filename.

(2) The general rule for geometry is widthxheight+x+y. Your coordinates are in the wrong positions.

Try:

Code: Select all

red=`convert $ORIGFILE[1x1+${XVAL}+${YVAL1}] -format "%[fx:round(255*u.r)]" info:`
etc
snibgo's IM pages: im.snibgo.com
mfillpot

Re: rbg values of a pixel

Post by mfillpot »

Thank you for the prompt response, now everything makes sense and works correctly. :D

I will spend a lot more time using imagemagick, the tools and functions are far more complexed than I anticipated.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: rbg values of a pixel

Post by fmw42 »

mfillpot

Re: rbg values of a pixel

Post by mfillpot »

I have been going over the array of command on the first link, but I had not visited the contents of the second link. It is now bookmarked.

And since you helped me, I I will share my script so others can use it in the future.

The goal of the script is to quickly apply the copyright notice on a picture and add a copywight notice in the comments, I have also applied the function to sample the color on the pixel that the notice starts on and use the inverted value for the font color... enjoy

Code: Select all

#!/bin/bash

# Add the copyright notice to an image file

LINE1="© Author Name "`date +%Y`
LINE2="  City, State"

FNT="~/fontname.TTF"
FONTSIZE=24

# how many pixels from the left should the text start
XLEN=150
# how many pixels from the bottom should the text start
YLEN=20

CWD=`dirname "$1"`
ORIGFILE="$CWD/$1"

XVAL=`identify $ORIGFILE |cut -d " " -f 3|cut -d "x" -f 1`
YVAL=`identify $ORIGFILE |cut -d " " -f 3|cut -d "x" -f 2`
XVAL=$(($XVAL -$XLEN))
YVAL1=$(($YVAL -$YLEN))

# Extract the rgb value for the pixel that the notice starts on
red=`convert $ORIGFILE[1x1+${XVAL}+${YVAL1}] -format "%[fx:round(255*u.r)]" info:`
green=`convert $ORIGFILE[1x1+${XVAL}+${YVAL1}] -format "%[fx:round(255*u.g)]" info:`
blue=`convert $ORIGFILE[1x1+${XVAL}+${YVAL1}] -format "%[fx:round(255*u.b)]" info:`

# invert the values of the pixel for the notice color
red=$((255-$red))
green=$((255-$green))
blue=$((255-$blue))

TEXTCOLOR="rgb($red,$blue,$green)"

convert $ORIGFILE \
-font $FNT -pointsize $FONTSIZE -fill $TEXTCOLOR -annotate +$XVAL+$YVAL1 "$LINE1" \
-comment "$LINE1 $LINE2" \
$ORIGFILE
Post Reply