是否可以检索0-255范围内PNG文件像素的alpha值?

时间:2016-12-10 18:53:18

标签: php png gd alpha alpha-transparency

在最近的一次比赛中,我被赋予了从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来尝试将错误范围内的值伪造成正确的值,但无济于事。

2 个答案:

答案 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);
  • 引用代码中未定义的变量'$ image'。
  • 使用getimagesize意味着$ image是文件名。
  • 所以此行从文件名中获取宽度和高度。

当我测试它时,这行破坏了代码。 你已经有了自己的答案,但这是为了后代。 考虑到代码,我觉得:

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

更合乎逻辑(并且实际上有效)