什么可能导致 imagecolorsforindex() 出现“颜色索引超出范围”错误?

问题描述 投票:0回答:2

当对一大堆 JPG、PNG 和 GIF 文件进行补丁大小调整时,PHP 意外地死机,并显示以下错误消息:

imagecolorsforindex() [function.imagecolorsforindex]: 颜色指数 226 超出范围

相关代码片段是:

protected function preserveTransparency($img, $resized, $ftype) {

    if (($ftype == IMAGETYPE_PNG) || ($ftype == IMAGETYPE_GIF)) {
        $tidx = imagecolortransparent($img);
        if ($tidx >= 0) {
          $transColor = imagecolorsforindex($img, $tidx);
          $tidx = imagecolorallocate($resized, $transColor['red'], $transColor['green'], $transColor['blue']);
          imagefill($resized, 0, 0, $tidx);
          imagecolortransparent($resized, $tidx);
        } elseif ($ftype == IMAGETYPE_PNG) {
            imagealphablending($resized, false);
            imagesavealpha($resized, true);
            $transparent = imagecolorallocatealpha($resized, 255, 255, 255, 127);
            imagefill($resized, 0, 0, $transparent);
        }
    }
}

如果已经由

imagecolortransparent
返回,颜色索引怎么可能不存在?

php image-processing image-manipulation imagemagick gd
2个回答
12
投票

听起来

imagecolortransparent($img)
返回的索引大于相关图像的托盘大小。

透明度颜色的索引是图像的属性,而不是托盘的属性,因此可以使用在托盘大小之外设置的索引来创建图像,但我希望 PHP 能够检测到在这种情况下,从

imagecolortransparent()
返回 -1。

您可以通过在代码中添加对 imagecolorstotal 的调用来检查是否发生了这种情况:

    $tidx = imagecolortransparent($img);
    $palletsize = imagecolorstotal($img);
    if ($tidx >= 0 && $tidx < $palletsize) {
      $transColor = imagecolorsforindex($img, $tidx);

0
投票

我知道这是一个老问题,但我来到这里是因为切换到 PHP 8.x 开始在我编写的图形程序中出现这个问题。我搜索了很长一段时间,发现它被标记为 PHP bug,但我从未真正找到解决方案。我修复了我的代码,所以我想分享我的解决方案。也许它会适用于您的问题。

问题实际上发生在您尝试查找透明颜色的文件首次保存时,而不是在其他 GD 函数检查该文件时。在使用 imagegif 保存文件之前,需要显式定义透明颜色。如果这样做,以后对 GD 函数的调用可以识别透明颜色,并且不会抛出超出范围的错误。下面是 gif 保存的示例片段。

$black = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $black);
imagegif($im, $filename);
© www.soinside.com 2019 - 2024. All rights reserved.