2016-12-10 12 views
1

В недавнем конкурсе мне была дана задача извлечь двоичные данные (другой PNG) из альфа-канала файла изображения PNG. Данные были закодированы таким образом, что если я прочитал значения в альфа-канале для каждого пикселя из верхнего левого угла (например, 80,78,71,13,10,26,10) до определенной точки, тогда полученные данные сформировали бы другое изображение.Возможно ли получить альфа-значение пикселя PNG-файла в диапазоне 0-255?

Первоначально я попытался выполнить эту задачу с помощью 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.

Итак, мой вопрос: есть ли any способ Я мог бы прочитать альфа-канал PNG-файла, который бы вернул значения в диапазоне от 0 до 255, а не 0-127, закодированное ограничение PHP и/или GD?

Для записи я попытался использовать ($colors['alpha']/127)*255, чтобы попытаться подделать значение в неправильном диапазоне до нужного, но безрезультатно.

ответ

2

Это ограничение GD. Согласно https://bitbucket.org/libgd/gd-libgd/issues/132/history-behind-7-bit-alpha-component в источнике GD он говорит:

Г.Д. имеет только 7 бит разрешения альфа-канал, и 127 является прозрачными, непрозрачными 0. Момент удобства, срок службы Совместимость.

Если установить расширение PHP ImageMagick, вы можете получить альфа-значение между 0-255 для пикселя (скажем, при х = 300 и у = 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

+0

Это Г.Д. примечание интересно @wizard, как я использую ImageColorAt в кусок кода, и спрашивает, почему я не был получение точных результатов. Я попробую версию Imagemagick позже и посмотрю, что я получу. В то время, когда я писал, Imagick недоступен, и использование ImageColorAt было проще, чем вызов Imagemagick с exec(). Я полагаю, что я должен обновить свой код, поскольку многое изменилось с тех пор, как я его написал! – Bonzo

+0

Я действительно искал изображение неправильно, поэтому это решение не сработало сначала, но после исправления циклов 'for' скрипт вернул именно то, что мне нужно. Спасибо за ответ. – SeinopSys

+0

Попробуйте отключить функцию imagealphablending. '$ img = imagecreatefrompng ('image.png');' 'imagealphablending ($ img, false);' 'imagesavealpha ($ img, true); ' –

-1

В коде:

list($width, $height) = getimagesize($image); 
  • ссылается на переменную '$ image', которая не определена в коде.
  • с использованием метода getimagesize $ image является именем файла.
  • так что эта строка будет иметь ширину и высоту от имени файла.

Эта строка нарушила код, когда я его протестировал. У вас уже есть свой ответ, но это для потомков. Учитывая код, я чувствую:

$width=imagesx ($ir); 
$height=imagesy ($ir); 

Было бы более логично (и на самом деле работает)

+0

Этот вопрос остался там, когда я урезал фактический код вопроса, я исправил его сейчас. – SeinopSys