在最近的一次比赛中,我被赋予了从PNG图像文件的alpha通道中提取二进制数据(另一个PNG)的任务。数据的编码方式是,如果我从左上角(例如80,78,71,13,10,26,10
)读取每个像素的alpha通道中的值到特定点,那么结果数据将形成另一个图像。
最初我尝试使用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文件的alpha通道,该通道将返回0到255范围内的值而不是0-127,或者是这是PHP和/或GD的硬编码限制吗?
为了记录,我尝试使用($colors['alpha']/127)*255
来尝试将错误范围内的值伪造成正确的值,但无济于事。
答案 0 :(得分:2)
这是GD的限制。根据{{3}},在GD来源中它说:
gd只有7位alpha通道分辨率,而127是 透明,0不透明。一刻的便利,一生的 兼容性。
如果你安装ImageMagick PHP扩展,你可以得到一个像素的0-255之间的alpha值(让我们说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://bitbucket.org/libgd/gd-libgd/issues/132/history-behind-7-bit-alpha-component
ImageMagick for PHP(名为Imagick):https://www.imagemagick.org
答案 1 :(得分:-1)
在您的代码中:
list($width, $height) = getimagesize($image);
当我测试它时,这行破坏了代码。 你已经有了自己的答案,但这是为了后代。 考虑到代码,我觉得:
$width=imagesx ($ir);
$height=imagesy ($ir);
更合乎逻辑(并且实际上有效)