На недавнем конкурсе мне было поручено извлечь двоичные данные (еще один PNG) из альфа-канала файла изображения PNG. Данные были закодированы таким образом, что, если я прочитал значения в альфа-канале для каждого пикселя сверху слева (например, 80,78,71,13,10,26,10
) до определенной точки, тогда результирующие данные будут формировать другое изображение.
Первоначально я пытался выполнить эту задачу с помощью PHP, но я наткнулся на контрольно-пропускной пункт, который я не смог преодолеть. Рассмотрим код ниже:
function pad($hex){
return strlen($hex) < 2 ? "0$hex" : $hex;
}
$channel = '';
$image = 'image.png';
$ir = imagecreatefrompng($image);
imagesavealpha($ir, true);
list($width, $height) = getimagesize($image);
for ($y = 0; $y < $height; $y++){
for ($x = 0; $x < $width; $x++){
$pixel = imagecolorat($ir, $x, $y);
$colors = imagecolorsforindex($ir, $pixel);
$a = pad(dechex($colors['alpha']));
$channel.= $a;
}
}
После выполнения этого я заметил, что вывод не содержал магическое число PNG, и я просто не знал, что пошло не так. После небольшой копки я узнал, что $colors['alpha']
содержал только значения, меньшие или равные 127. Из-за того, что данные были закодированы с диапазоном 0-255, я не смог найти способ извлечь его и в итоге (успешно) решил проблему с помощью node.js. ,
Итак, мой вопрос: есть ли любой Я мог бы прочитать альфа-канал PNG-файла, который бы возвращал значения в диапазоне от 0 до 255, а не 0-127, или это жестко ограниченное ограничение PHP и / или GD?
Для записи я пытался использовать ($colors['alpha']/127)*255
чтобы попытаться подделать значение в неправильном диапазоне к правильному, но безрезультатно.
Это ограничение GD. В соответствии с https://bitbucket.org/libgd/gd-libgd/issues/132/history-behind-7-bit-alpha-component, в источнике GD говорится:
GD имеет только 7 битов разрешения альфа-канала, а 127
прозрачный, 0 непрозрачный. Момент удобства, целая жизнь
совместимость.
Если вы установите расширение ImageMagick PHP, вы можете получить альфа-значение между 0-255 для пикселя (скажем, с x = 300 и y = 490) следующим образом:
$image = new Imagick(__DIR__ . DIRECTORY_SEPARATOR . 'image.png');
$x = 300;
$y = 490;
$pixel = $image->getImagePixelColor($x, $y);
$colors = $pixel->getColor(true);
echo 'Alpha value: ' . round($colors['a'] * 255, 0);
ImageMagick: https://www.imagemagick.org
ImageMagick для PHP (называется Imagick): http://php.net/manual/en/book.imagick.php
В вашем коде:
list($width, $height) = getimagesize($image);
Эта строка сломала код, когда я тестировал его.
У вас уже есть свой ответ, но это для потомков.
Учитывая код, я чувствую:
$width=imagesx ($ir);
$height=imagesy ($ir);
Было бы более логичным (и на самом деле работает)