Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get image whole pixel's RGB color with ImageMagick?

Tags:

imagemagick

I'm new to ImageMagick.

I want to know image's RGB color of whole pixel.

I already know how to get one pixel's RGB color.

But I don't know how to get all pixel's data with one command.

Executing each command on every pixel is so heavy that can't use it.

The best command result is like this...

#x,y={R,G,B}
1,1={100,230,105},
1,2={100,230,105},
1,3={100,230,135},
...
...
like image 605
SHRIN Avatar asked Oct 29 '14 08:10

SHRIN


2 Answers

A Further Option

If you want to amortize the cost of running identify across lots of images for better performance, you can do something like this - where %k gives you the number of colours and %n gives you the filename:

identify -format "%k:%f\n" *.jpg

Output

290972:7T6Dj.jpg
3641:a.jpg
8349:b.jpg
3019:back.jpg
3122:background.jpg
83155:blion.jpg
35136:brDaP.jpg
37106:cartesian.jpg

There must be a system() or shell_exec() or popen() in Java that could run that so you could get the output.

Updated Answer

If you simply want to check whether the image consists of only a single colour, you can ask ImageMagick to count the colours, like this (using the same image as below):

identify -format "%k" a.gif
3

I am not sure how you do that with Java, but in Ruby you do:

image["%[k]"]

and in Perl you do:

my $image = Image::Magick->new;
$image->ReadImage("c.png");

print $image->Get("%[k]");

Original Answer

You provided no details of your environment, programming language, application or anything much, however, this may get you started.

Let's create a small image from the command line, with 3 squares, each 4x4 pixels, one red, one green and one blue all in a horizontal row:

convert -size 4x4 xc:red xc:green xc:blue +append a.gif

I'll zoom it in so you can see it:

enter image description here

Now, we can look at it in text format:

convert -size 4x4 xc:red xc:green xc:blue +append -depth 8 txt:
# ImageMagick pixel enumeration: 12,4,255,srgb
0,0: (255,0,0)  #FF0000  red
1,0: (255,0,0)  #FF0000  red
2,0: (255,0,0)  #FF0000  red
3,0: (255,0,0)  #FF0000  red
4,0: (0,128,0)  #008000  green
5,0: (0,128,0)  #008000  green
6,0: (0,128,0)  #008000  green
7,0: (0,128,0)  #008000  green
8,0: (0,0,255)  #0000FF  blue
9,0: (0,0,255)  #0000FF  blue
10,0: (0,0,255)  #0000FF  blue
11,0: (0,0,255)  #0000FF  blue
0,1: (255,0,0)  #FF0000  red
1,1: (255,0,0)  #FF0000  red
2,1: (255,0,0)  #FF0000  red
3,1: (255,0,0)  #FF0000  red
4,1: (0,128,0)  #008000  green
5,1: (0,128,0)  #008000  green
6,1: (0,128,0)  #008000  green
7,1: (0,128,0)  #008000  green
8,1: (0,0,255)  #0000FF  blue
9,1: (0,0,255)  #0000FF  blue
10,1: (0,0,255)  #0000FF  blue
11,1: (0,0,255)  #0000FF  blue
0,2: (255,0,0)  #FF0000  red
1,2: (255,0,0)  #FF0000  red
2,2: (255,0,0)  #FF0000  red
3,2: (255,0,0)  #FF0000  red
4,2: (0,128,0)  #008000  green
5,2: (0,128,0)  #008000  green
6,2: (0,128,0)  #008000  green
7,2: (0,128,0)  #008000  green
8,2: (0,0,255)  #0000FF  blue
9,2: (0,0,255)  #0000FF  blue
10,2: (0,0,255)  #0000FF  blue
11,2: (0,0,255)  #0000FF  blue
0,3: (255,0,0)  #FF0000  red
1,3: (255,0,0)  #FF0000  red
2,3: (255,0,0)  #FF0000  red
3,3: (255,0,0)  #FF0000  red
4,3: (0,128,0)  #008000  green
5,3: (0,128,0)  #008000  green
6,3: (0,128,0)  #008000  green
7,3: (0,128,0)  #008000  green
8,3: (0,0,255)  #0000FF  blue
9,3: (0,0,255)  #0000FF  blue
10,3: (0,0,255)  #0000FF  blue
11,3: (0,0,255)  #0000FF  blue

But you say that it takes too long to get one 1 pixel, so you can convert the image to a file that is just pure RGB values and read that:

convert -size 4x4 xc:red xc:green xc:blue +append -depth 8 x.rgb

If we look at the file, we can see it is 144 pixels long, 16 red pixels, 16 green pixels, 16 blue pixels - therefore 48 pixels altogether - and each one with a single byte of R, G and B. (48x3=144)

ls -l x.rgb
-rw-r--r--  1 mark  staff  144 29 Oct 11:06 x.rgb

ImageMagick uses the file extension to determine the format, and rgb means RGB!. If you want to use an extension different from .rgb, you can tell ImageMagick like this:

convert -size 4x4 xc:red xc:green xc:blue +append -depth 8 RGB:x.raw

Now let's look at the file in hex:

xxd -g3 -c12 x.rgb
0000000: ff0000 ff0000 ff0000 ff0000  ............
000000c: 008000 008000 008000 008000  ............
0000018: 0000ff 0000ff 0000ff 0000ff  ............
0000024: ff0000 ff0000 ff0000 ff0000  ............
0000030: 008000 008000 008000 008000  ............
000003c: 0000ff 0000ff 0000ff 0000ff  ............
0000048: ff0000 ff0000 ff0000 ff0000  ............
0000054: 008000 008000 008000 008000  ............
0000060: 0000ff 0000ff 0000ff 0000ff  ............
000006c: ff0000 ff0000 ff0000 ff0000  ............
0000078: 008000 008000 008000 008000  ............
0000084: 0000ff 0000ff 0000ff 0000ff  ............

Hopefully you can see the first line is 4 red pixels, the second line is 4 green ones...

So, in short, if you want to just read pure binary data from an image into a C program, you can do this:

convert YourImage.jpg -depth 8 RGB:- | YourProgram
like image 115
Mark Setchell Avatar answered Nov 12 '22 08:11

Mark Setchell


There is a newer option in ImageMagick that is extremely fast. It is similar to txt: but lists the data as comma separated triplets (x,y,color where color is a color name or rgb(rr,gg,bb). Using Mark's red,green,blue image:

time convert WM9qM.gif sparse-color:

0,0,red 1,0,red 2,0,red 3,0,red 4,0,red 5,0,red 6,0,red 7,0,red 8,0,red 9,0,red 10,0,red 11,0,red 12,0,red 13,0,red 14,0,red 15,0,red 16,0,red 17,0,red 18,0,red 19,0,red 20,0,red 21,0,red 22,0,red 23,0,red 24,0,red 25,0,red 26,0,red 27,0,red 28,0,red 29,0,red 30,0,red 31,0,red 32,0,green 33,0,green 34,0,green 35,0,green 36,0,green 37,0,green 38,0,green 39,0,green 40,0,green 41,0,green 42,0,green 43,0,green 44,0,green 45,0,green 46,0,green 47,0,green 48,0,green 49,0,green 50,0,green 51,0,green 52,0,green 53,0,green 54,0,green 55,0,green 56,0,green 57,0,green 58,0,green 59,0,green 60,0,green 61,0,green 62,0,green 63,0,green 64,0,blue 65,0,blue 66,0,blue 67,0,blue 68,0,blue 69,0,blue 70,0,blue 71,0,blue 72,0,blue 73,0,blue 74,0,blue 75,0,blue 76,0,blue 77,0,blue 78,0,blue 79,0,blue 80,0,blue 81,0,blue 82,0,blue 83,0,blue 84,0,blue 85,0,blue 86,0,blue 87,0,blue 88,0,blue 89,0,blue 90,0,blue 91,0,blue 92,0,blue 93,0,blue 94,0,blue 95,0,blue 0,1,red 1,1,red 2,1,red 3,1,red 4,1,red 5,1,red 6,1,red 7,1,red 8,1,red 9,1,red 10,1,red 11,1,red 12,1,red 13,1,red 14,1,red 15,1,red 16,1,red 17,1,red 18,1,red 19,1,red 20,1,red 21,1,red 22,1,red 23,1,red 24,1,red 25,1,red 26,1,red 27,1,red 28,1,red 29,1,red 30,1,red 31,1,red 32,1,green 33,1,green 34,1,green 35,1,green 36,1,green 37,1,green 38,1,green 39,1,green 40,1,green 41,1,green 42,1,green 43,1,green 44,1,green 45,1,green 46,1,green 47,1,green 48,1,green 49,1,green 50,1,green 51,1,green 52,1,green 53,1,green 54,1,green 55,1,green 56,1,green 57,1,green 58,1,green 59,1,green 60,1,green 61,1,green 62,1,green 63,1,green 64,1,blue 65,1,blue 66,1,blue 67,1,blue 68,1,blue 69,1,blue 70,1,blue 71,1,blue 72,1,blue 73,1,blue 74,1,blue 75,1,blue 76,1,blue 77,1,blue 78,1,blue 79,1,blue 80,1,blue 81,1,blue 82,1,blue 83,1,blue 84,1,blue 85,1,blue 86,1,blue 87,1,blue 88,1,blue 89,1,blue 90,1,blue 91,1,blue 92,1,blue 93,1,blue 94,1,blue 95,1,blue 0,2,red 1,2,red 2,2,red 3,2,red 4,2,red 5,2,red 6,2,red 7,2,red 8,2,red 9,2,red 10,2,red 11,2,red ....

real    0m0.035s
user    0m0.024s
sys 0m0.007s

If you want one line per pixel, you can do

convert WM9qM.gif sparse-color: | tr " " "\n"

0,0,red
1,0,red
2,0,red
3,0,red
4,0,red
5,0,red
6,0,red
7,0,red
8,0,red
9,0,red
10,0,red
11,0,red
12,0,red
13,0,red
14,0,red
15,0,red
16,0,red
17,0,red
18,0,red
19,0,red
20,0,red
21,0,red
22,0,red
23,0,red
24,0,red
25,0,red
26,0,red
27,0,red
28,0,red
29,0,red
30,0,red
31,0,red
32,0,green
like image 25
fmw42 Avatar answered Nov 12 '22 06:11

fmw42