当对一大堆 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
返回,颜色索引怎么可能不存在?
听起来
imagecolortransparent($img)
返回的索引大于相关图像的托盘大小。
透明度颜色的索引是图像的属性,而不是托盘的属性,因此可以使用在托盘大小之外设置的索引来创建图像,但我希望 PHP 能够检测到在这种情况下,从
imagecolortransparent()
返回 -1。
您可以通过在代码中添加对 imagecolorstotal 的调用来检查是否发生了这种情况:
$tidx = imagecolortransparent($img);
$palletsize = imagecolorstotal($img);
if ($tidx >= 0 && $tidx < $palletsize) {
$transColor = imagecolorsforindex($img, $tidx);
我知道这是一个老问题,但我来到这里是因为切换到 PHP 8.x 开始在我编写的图形程序中出现这个问题。我搜索了很长一段时间,发现它被标记为 PHP bug,但我从未真正找到解决方案。我修复了我的代码,所以我想分享我的解决方案。也许它会适用于您的问题。
问题实际上发生在您尝试查找透明颜色的文件首次保存时,而不是在其他 GD 函数检查该文件时。在使用 imagegif 保存文件之前,需要显式定义透明颜色。如果这样做,以后对 GD 函数的调用可以识别透明颜色,并且不会抛出超出范围的错误。下面是 gif 保存的示例片段。
$black = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $black);
imagegif($im, $filename);