What could cause a "color index out of range" error for imagecolorsforindex()?
Asked Answered
M

2

5

When doing a patch resize to a big bunch of JPG, PNG and GIF files, PHP drops dead quite unexpectedly with the following error message:

imagecolorsforindex() [function.imagecolorsforindex]: Color index 226 out of range

The relevant code fragment is:

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);
        }
    }
}

How could a color index not exist if was already returned by imagecolortransparent?

Mistletoe answered 6/10, 2010 at 16:4 Comment(1)
I solved this resaving the image file. Although I could open it with imagecreatepng() and show it with imagepng(). After googling a lot, seems it's not related with PHP, because there is no info about it...Vikkivikky
M
12

It sounds like the index returned by imagecolortransparent($img) is larger than the pallet size of the image in question.

The index of the transparency color is a property of the image, rather than a property of the pallet, so it's possible that an image could be created with this index set outside the pallet size, but I would have hoped that PHP would have detected this and returned -1 from imagecolortransparent() in this situation.

You could check if this is what is happening by adding a call to imagecolorstotal to your code:

    $tidx = imagecolortransparent($img);
    $palletsize = imagecolorstotal($img);
    if ($tidx >= 0 && $tidx < $palletsize) {
      $transColor = imagecolorsforindex($img, $tidx);
Morava answered 9/10, 2010 at 21:50 Comment(1)
or... imagecolorsforindex($img, imagecolorstotal($img) - 1);Mayflower
C
0

I know this is an old question, but I arrived here because switching to PHP 8.x started giving me this issue in a graphics program I wrote. I searched for quite a while and found it to be labeled a PHP bug but I never really found a solution. I fixed my code so I would like to share my solution. Maybe it will apply to your problem.

The problem actually occurs when the file you are trying to find the transparent color for is first saved, not when it is examined by other GD functions. Before saving the file with imagegif one needs to explicitly define the transparent color. If this is done the later calls to GD functions can identify the transparent color and will not throw the out of range error. Example snippet for a gif save below.

$black = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $black);
imagegif($im, $filename);
Crossjack answered 3/9, 2023 at 16:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.