Search code examples
perlgdrgbpixel

How do I get the correct rgb value for a pixel with GD?


I have a 4x1 pixel png where the left most pixel is white (#ffffff), the second pixel is red (#ff0000), the third pixel is green (#00ff00) and the right most pixel is blue (#0000ff), almost invisible here: enter image description here.

With the following perl script, I tried to read the rgb values for each pixel:

use warnings;
use strict;

use GD;

my $image = new GD::Image('white-red-green-blue.png') or die;

for (my $x=0; $x<4; $x++) {
  my $index = $image->getPixel($x, 0);
  my ($r,$g,$b) = $image->rgb($index);

  printf "%3d %3d %3d\n", $r, $g, $b;
}

Much to my surprise, it printed

252 254 252
252   2   4
  4 254   4
  4   2 252

whereas I expected

255 255 255
255   0   0
  0 255   0
  0   0 255

Why does the script report wrong rgb values and how can I teach it to report the correct ones?

Edit As per mpapec's question, the output of base64 white-red-green-blue.png is

iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAIAAAB2XpiaAAAAAXNSR0IArs4c6QAAAARnQU1B
AACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAASSURBVBhXY/gPBAwMDEDM8B8AL90F
+8V5iZQAAAAASUVORK5CYII=

Edit II As per dgw's suggestion, I also tried my $image = newFromPng GD::Image('white-red-green-blue.png') or die; but with the same result.

Update: I have tried the same thing with Image::Magick instead of GD:

use warnings;
use strict;

use Image::Magick;

my $image = Image::Magick->new or die;
my $read = $image -> Read('white-red-green-blue.png');

for (my $x=0; $x<4; $x++) {

  my @pixels = $image->GetPixels(
      width     => 1,
      height    => 1,
      x         => $x,
      y         => 0,
      map       =>'RGB',
      #normalize => 1
  );

  printf "%3d %3d %3d\n", $pixels[0] / 256, $pixels[1] / 256, $pixels[2] / 256;

}

and, somewhat unsurpringly, it prints the expected

255 255 255
255   0   0
  0 255   0
  0   0 255

Solution

  • Updated

    Ok, it works fine with your image if you do this:

    GD::Image->trueColor(1);
    

    BEFORE starting anything with GD. I think it is because one image is palettized and the other is not. See here:

    enter image description here

    Original Answer

    It works fine on my iMac. I generated the image with ImageMagick like this:

    convert -size 1x1! xc:rgb\(255,255,255\) xc:rgb\(255,0,0\) xc:rgb\(0,255,0\) xc:rgb\(0,0,255\) +append wrgb.png
    
    ./go.pl
    255 255 255
    255   0   0
    0 255   0
    0   0 255
    

    I suspect your image is not being generated correctly.