Perl & Image::Magick, получение значений цвета по пикселям

Я использую Perl и модуль Image::Magick для обработки некоторых файлов JPEG.

Я использую подпрограмму GetPixels для получения компонентов RGB каждого пикселя.

e.g.

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');

Я обнаружил, что getPixels возвращает два байта на канал, например.

$VAR1 = [
          46260,
          45232,
          44975
        ];

$VAR1 = [
          58271,
          58949,
          60330
        ];

Перед вызовом Resize: (в этом примере) цвет назначенного пикселя — #b4b0af, а возвращаемые значения — 0xB4B4, 0xB0B0, 0xAFAF. Я не понимаю, почему это так, но я могу справиться с этим, используя МОД 256;

Но после вызова Resize возвращаемые значения никаким очевидным образом не соответствуют фактическим значениям, которые я нахожу в выходном файле (verify.jpg).

Является ли Image::Magick просто сверхточным (с учетом шорт, а не байтов)?
И объясняет ли сжатие JPEG несоответствие между выводом второго дампера и содержимым 'verify.jpg'?


person aidan    schedule 09.09.2010    source источник


Ответы (3)


Прочтите все о цветах в ImageMagick, включая их квантовую глубину:

ImageMagick может быть скомпилирован для поддержки 32- или 64-битных пикселей типа PixelPacket. Это контролируется значением определения QuantumDepth. По умолчанию используются 64-битные пиксели, что обеспечивает наилучшую точность.

Вы также можете прочитать о том, как он выполняет уменьшение цвета.

person brian d foy    schedule 10.09.2010
comment
Спасибо, Брайан. Тоже очень интересные ссылки. Я думаю, что буду использовать более высокую точность, но из интереса, могу ли я предположить, что сдвиг вправо приведенных выше значений на 8 бит даст мне точное трехбайтовое представление цвета? - person aidan; 10.09.2010

Сжатие JPEG происходит с потерями, поэтому нет прямого соответствия между значениями пикселей перед сохранением и пикселями в сжатом изображении. Вам придется загрузить новое изображение, если вы хотите узнать, как его изменило сжатие.

person cjm    schedule 10.09.2010

Мне потребовалось некоторое время, чтобы решить ту же проблему для двоичных (черно-белых) размолвок:

    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";
    }

Принты (сокращенно):

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

Лучшего способа не нашел.

person Helmut Wollmersdorfer    schedule 29.07.2020