Загружать PNG и читать пиксели в PHP без GD? - PullRequest
1 голос
/ 07 марта 2009

Мне нужно прочитать точные неизмененные данные о пикселях (ARGB) из PNG-файла с истинным цветом, предпочтительно из PHP.

К сожалению, библиотека GD в PHP мешает альфа-каналу (сокращая его с 8-битного до 7-битного), что делает его непригодным для использования.

В настоящее время я предполагаю, что мои варианты:

  1. Внедрить мой собственный читатель PNG для извлечения необходимых данных.
  2. Используйте немного менее сломанный язык / библиотеку и вызывайте его из PHP как процесс оболочки или CGI.

Мне было бы интересно услышать какие-либо другие идеи или рекомендации относительно того или иного пути ...

Редактировать : Я думаю, что № 1 отсутствует. Я попытался передать поток данных IDAT в gzinflate (), но он просто дает мне ошибку данных. (Выполнение одинаковых действий с теми же данными вне PHP дает ожидаемый результат.)

Ответы [ 2 ]

3 голосов
/ 07 марта 2009

Как насчет ImageMagick?

<?php
$im = new Imagick("foo.png");
$it = $im->getPixelIterator();

foreach($it as $row => $pixels) {
    foreach ($pixels as $column => $pixel) {
        // Do something with $pixel
    }

    $it->syncIterator();
}
?>
0 голосов
/ 09 января 2011

Вы можете использовать функцию pngtopnm netpbm , чтобы преобразовать PNG в легко анализируемый PNM. Вот несколько наивный php-скрипт, который должен помочь вам получить то, что вам нужно:

<?php
$pngFilePath = 'template.png';
// Get the raw results of the png to pnm conversion
$contents = shell_exec("pngtopnm $pngFilePath");
// Break the raw results into lines
//  0: P6
//  1: <WIDTH> <HEIGHT>
//  2: 255
//  3: <BINARY RGB DATA>
$lines = preg_split('/\n/', $contents);

// Ensure that there are exactly 4 lines of data
if(count($lines) != 4)
    die("Unexpected results from pngtopnm.");

// Check that the first line is correct
$type = $lines[0];
if($type != 'P6')
    die("Unexpected pnm file header.");

// Get the width and height (in an array)
$dimensions = preg_split('/ /', $lines[1]);

// Get the data and convert it to an array of RGB bytes
$data = $lines[3];
$bytes = unpack('C*', $data);

print_r($bytes);
?>
...