Как проверить, имеет ли GIF прозрачность, используя GD?

Я видел эту тему, и решения отлично работают, но только для PNG. Есть ли решение для проверки прозрачности изображения GIF в PHP-GD?


person Angelo Joseph Salvador    schedule 29.01.2018    source источник
comment
См. руководство secure.php.net/manual/en/function.imagecolortransparent.php. — там много полезной информации.   -  person Funk Forty Niner    schedule 29.01.2018


Ответы (2)


Я меньше знаком с GIFs, чем с другими форматами, поэтому мои предположения могут быть неверными. Пожалуйста, дайте мне знать, если я ошибаюсь - будет оценен простой комментарий, а не голосование против.

Я предполагаю, что:

  • все GIF на поддонах,
  • альфа-компонент будет ненулевым (вероятно, 127) для любой прозрачной записи палитры,
  • кодировщики не добавляют элементы прозрачной палитры без необходимости.

Исходя из этого, следующий код загрузит GIF и проверит, что ни один элемент палитры не содержит прозрачности — вместо проверки каждого отдельного пикселя в очень медленном двойном цикле по высоте и ширине изображения:

<?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";
   }
?>
person Mark Setchell    schedule 29.01.2018
comment
Это хорошая идея для 8-битных изображений PNG, но GIF не поддерживает прозрачность альфа-канала. Один элемент палитры определяется как прозрачный цвет, и тогда любой пиксель, использующий этот элемент, будет отображаться прозрачным. - person timclutton; 29.01.2018
comment
@timclutton Спасибо за ваш вклад. Я не понимаю, о чем вы говорите - я создал несколько GIF-файлов с прозрачностью (используя ImageMagick), и каждый раз, когда я нахожу, что одна запись палитры имеет значение 127 в альфа-канале. Я не спорю и не утверждаю, что вы неправы, поскольку я сказал, что не очень хорошо знаком с GIF-файлами и хочу научиться сам, поэтому можете ли вы указать мне GIF с прозрачностью в любом пикселе, но без прозрачного пикселя в его палитре? Или объясните по-другому, чтобы я понял, пожалуйста? - person Mark Setchell; 29.01.2018
comment
Ваши ссылки на «альфа-канал» привлекли мое внимание. GIF не поддерживает альфа-канал, поэтому я не понимаю, как его можно проверить. Однако я не проверял ваш код, и GD часто ставит меня в тупик! Если у меня будет шанс, я сам запущу код. Рад оказаться неправым :-) - person timclutton; 29.01.2018
comment
@timclutton О, понятно. Я просто проверяю до 256 записей палитры, и каждая запись в палитре имеет красный, зеленый, синий и место для альфа-части. Я полагаю, что канал — плохое название для него, поскольку это всего лишь компонент элемента палитры. Я обновлю свой пост. - person Mark Setchell; 29.01.2018
comment
Здесь меня смутило использование «альфы»; но, запустив ваш код, я вижу, что вы совершенно правы. Очевидно, что GD умнее, чем я думал, и разумно возвращает настройку прозрачности в индексе alpha как 0 или 127. +1 от меня и своевременное напоминание всегда проверять свои предположения :-) - person timclutton; 29.01.2018

Этот код создает предварительный просмотр для GIF и проверяет прозрачность

$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);
person Delf    schedule 29.01.2018