简体   繁体   中英

Perl & Image::Magick, getting color values by pixel

I'm using Perl and the Image::Magick module to process some JPEGs.

I'm using the GetPixels sub to get the RGB components of each pixel.

eg

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

print Dumper \@pixels;

$img->Resize(
    width  => 1,
    height => 1,
    filter => 'Lanczos'
);

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

print Dumper \@pixels;

$img->Write('verify.jpg');

I've found that getPixels is returning two bytes per channel, eg

$VAR1 = [
          46260,
          45232,
          44975
        ];

$VAR1 = [
          58271,
          58949,
          60330
        ];

Before the call to Resize: (in this example) the colour of the designated pixel is #b4b0af, and the returned values are 0xB4B4, 0xB0B0, 0xAFAF. I don't understand why this is, but I can deal with it using MOD 256;

But after the call to Resize, the returned values don't correspond in any obvious way to the actual values I find in the output file (verify.jpg).

Is Image::Magick just being super-precise (accounting for the shorts instead of bytes)?
And does the JPEG compression account for the discrepancy between the second Dumper output and the contents of 'verify.jpg'?

Read all about colors in ImageMagick , including its quantum depth:

ImageMagick may be compiled to support 32 or 64 bit pixels of type PixelPacket. This is controlled by the value of the QuantumDepth define. The default is 64 bit pixels, which provides the best accuracy.

You might also like to read about how it does color reduction .

JPEG compression is lossy, so there's no direct correspondence between the pixel values before saving and the pixels in the compressed image. You'd have to load the new image if you want to find out how the compression modified it.

Took me some time to get the same problem solved for binary (black & white) tiffs:

    for my $y (0..$height-1) {
        my @pixels = $image->GetPixels(
            'width'   => 1,
            'height'  => 1,
            'x'       => 0,
            'y'       => $y,
            map       => 'RGB',
            normalize => 'True',
        );
        print  "$y: ",join(', ', @pixels),"\n";
    }

Prints (shortened):

627: 1, 1, 1
628: 1, 1, 1
629: 0, 0, 0
630: 0, 0, 0
631: 0, 0, 0
632: 0, 0, 0
633: 1, 1, 1
634: 1, 1, 1

Found no better way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM