0

I found the question How to check if an image has transparency using GD? but the the answers are all for PNG files. Is there a solution for checking if a GIF image has transparency in PHP using the GD extension?

miken32
  • 42,008
  • 16
  • 111
  • 154
  • 2
    See the manual https://secure.php.net/manual/en/function.imagecolortransparent.php - there is a lot of useful information in there. – Funk Forty Niner Jan 29 '18 at 03:02

2 Answers2

2

I am assuming that:

  • all GIFs are palettised,
  • the alpha component will be non-zero (probably 127) for any palette entry which is transparent,
  • encoders do not add transparent palette entries unnecessarily.

On that basis, the following code will load a GIF and check that no palette entry contains transparency - rather than checking every single pixel in a very slow double loop over height and width of an image:

<?php

function GIFcontainstransparency($fname){

   // Load up the image
   $src=imagecreatefromgif($fname);

   // Check image is palettised
   if(imageistruecolor($src)){
      fwrite(STDERR,"ERROR: Unexpectedly got a truecolour (non-palettised) GIF!");
   }

   // Get number of colours - i.e. number of entries in palette
   $ncolours=imagecolorstotal($src);

   // Check palette for any transparent colours rather than all pixels - to speed it up
   for($index=0;$index<$ncolours;$index++){
      $rgba = imagecolorsforindex($src,$index);
      if($rgba['alpha']>0){
         return true;
      }
   }
   return false;
}

////////////////////////////////////////////////////////////////////////////////
// main
////////////////////////////////////////////////////////////////////////////////

   if(GIFcontainstransparency("image.gif")){
      echo "Contains transparency";
   } else {
      echo "Is fully opaque";
   }
?>
miken32
  • 42,008
  • 16
  • 111
  • 154
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • This is a neat idea for 8-bit PNG images, but GIF doesn't support alpha channel transparency. A single palette entry is defined as the transparent colour and then any pixel using that entry will be rendered transparent. – timclutton Jan 29 '18 at 17:02
  • @timclutton Thank you for your inputs. I don't understand what you are saying though - I created some GIFs with transparency (using ImageMagick) and every time I find one palette entry has the value 127 in the alpha channel. I am not arguing or suggesting you are wrong, as I said I am not that familiar with GIFs and want to learn myself, so can you point me to a GIF with transparency in any pixel but no transparent pixel in its palette? Or explain a different way so I get the hang of it please? – Mark Setchell Jan 29 '18 at 17:10
  • Your references to ‘alpha channel’ caught my attention. GIF doesn’t support an alpha channel so I don’t understand how you can check for it. I haven’t tested your code, though, and GD frequently confounds me! If I get a chance I’ll run the code myself. Happy to be proven wrong :-) – timclutton Jan 29 '18 at 17:58
  • @timclutton Oh I see. I just check up to 256 palette entries and each entry in the palette has a Red, Green, Blue and space for an Alpha part as well. I suppose channel is poor name for it since it is just a component of a palette entry. I'll update my post. – Mark Setchell Jan 29 '18 at 18:20
  • The use of 'alpha' confused me here; but having run your code I can see you are quite correct. Clearly GD is cleverer than I thought and intelligently returns the transparency setting in the `alpha` index as either `0` or `127`. +1 from me and a timely reminder to always test your assumptions :-) – timclutton Jan 29 '18 at 20:02
0

This code create preview for gifs and check transparency

$width=64;
$height=64;
$src='original.gif';
$dst='preview.gif';
list($width_orig, $height_orig) = getimagesize($src);

$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromgif($src);

$transparent_index = imagecolortransparent($image);
$palette_colors_cnt = imagecolorstotal($image);
if ($transparent_index >= 0) {
    imagepalettecopy($image, $image_p);
    imagefill($image_p, 0, 0, $transparent_index);
    imagecolortransparent($image_p, $transparent_index);
    imagetruecolortopalette($image_p, true, $palette_colors_cnt);
}
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagegif($image_p, $dst);
Delf
  • 113
  • 1
  • 1
  • 5