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

Is it possible to retrieve the alpha value of a pixel of a PNG file in the 0-255 range?

在最近的比赛中,我的任务是从 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 and/or GD 的硬编码限制?

郑重声明,我尝试使用 ($colors['alpha']/127)*255 来尝试将不正确范围内的值伪造为正确的值,但无济于事。

这是GD的限制。根据 https://bitbucket.org/libgd/gd-libgd/issues/132/history-behind-7-bit-alpha-component,在 GD 源中它说:

gd has only 7 bits of alpha channel resolution, and 127 is transparent, 0 opaque. A moment of convenience, a lifetime of compatibility.

如果您安装 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://www.imagemagick.org

用于 PHP 的 ImageMagick(称为 Imagick):http://php.net/manual/en/book.imagick.php

在您的代码中:

list($width, $height) = getimagesize($image);
  • 引用了代码中未定义的变量“$image”。
  • 使用 getimagesize 意味着 $image 是一个文件名。
  • 所以这一行从文件名中获取宽度和高度。

这一行在我测试时破坏了代码。 您已经有了答案,但这是为了后代。 考虑代码,感觉:

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

会更合乎逻辑(并且实际可行)