php gd читает необработанные данные пикселей - PullRequest
2 голосов
/ 27 марта 2011

У меня есть следующий php-скрипт:

<?php
class GimFile {
    public $data = '';
    public $header = '';
    public $rgba = '';
    public $width = 0;
    public $height = 0;
    public function __construct($imagedata) {
        $this->data = $imagedata;
        if (substr($this->data, 1, 3) != 'GIM') {
            exit("This data is not in GIM format");
        }

        $this->header = substr($this->data, 0, 128);
        $this->rgba = substr($this->data, 128);

        // PHP can't unpack signed short from big-endian
        // so we unpack it as unsigned, and subtract 2^16 if >2^15
        $dimensions = array_values(unpack("n2", substr($this->header, 72, 76)));
        for($i = 0; $i < count($dimensions); $i++) {
            if($dimensions[$i] >= pow(2, 15)) {
                $dimensions[$i] -= pow(2, 16);
            }
        }

        list($this->width, $this->height) = $dimensions;
    }
    public function save($dest) {
        //create image
        $img = imagecreatetruecolor($this->width, $this->height);
        //fill by iterating through your raw pixel data
        for($x = 0; $x < $this->width; $x++) {
            for($y = 0; $y < $this->height; $y++) {
                $pos = ($y * $this->width + $x) * 4;
                list($red, $green, $blue, $alpha) = array_values(unpack("C4", substr($this->rgba, $pos, $pos+4)));
                $alpha >>= 1; // alpha transprancy is saved as 8bit, we need 7 bit
                $color = imagecolorallocatealpha ( $img, $red, $green, $blue, $alpha );
                imagesetpixel($img, $x, $y, $color);
            }
        }
        imagepng($img, $dest);
        imagedestroy($img);
    }
}

header('Content-type: image/png');
$contents = file_get_contents('gim');
$gim = new GimFile($contents);
$gim->save('lol.png');

?>

Предполагается прочитать необработанные двоичные данные в качестве аргумента и сохранить их как файл .png.Эти данные содержат следующее:
первые 128 байтов являются заголовками, из которых смещение 72 и 74 содержат ширину и высоту соответственно (подписанный короткий большой порядок байтов).Эти данные анализируются в конструкторе.Остальные данные - это необработанные данные RGBA.
Функция сохранения обрабатывает необработанные данные RGBA (итерирует каждый пиксель), находит цвет и записывает в новое изображение такой же ширины и высоты.и затем сохраняет его в файл.
однако результаты по какой-то причине неверны.

Используется следующий файл, содержащий необходимые данные: http://2971.a.hostable.me/gim/gim
Ожидается следующий png: http://2971.a.hostable.me/gim/expected.png
Генерируется следующий png: http://2971.a.hostable.me/gim/output.png

Чтобы приблизиться к ожидаемому результату, нужно было установить $ alpha на 0, но это привело к следующему: http://2971.a.hostable.me/gim/noalpha.png

Может ли кто-нибудь помочь исправить сценарий для получения ожидаемогорезультат?

Заранее спасибо.

Хош

1 Ответ

1 голос
/ 28 марта 2011

Вместо изображения у меня есть сообщение ' Невозможно отобразить изображение "http://localhost/gim/gim.php", поскольку оно содержит ошибки ', записанные на холсте PNG. Я использовал файл gim ( 65,393 байт ) и протестировал ваш скрипт на localhost (имеет поддержку библиотеки GD). Кроме того, выходной файл lol.png выглядит как радуга (ширина: 128px, высота: 128px, bitdepth: 24). Вы уверены, что это это правильный код (не какая-то ваша модификация, которая не работает)? Я хочу помочь, но не могу понять, что формат ' gim '.

P.S. gim.php - это мой php-скрипт, в который я помещаю ваш код в папку ./gim на localhost.

Скажите мне что-нибудь, если вы используете 4 байта для кодирования каждого пикселя в изображении 128x128 ... необработанные данные ДОЛЖНЫ быть не менее 65 536 байтов + заголовок ... так что другой вопрос, если этот код верен, что не так с файл 'gim', потому что он всего 65 393 байта?

...