it-swarm.com.ru

Изменение размера анимированного файла GIF без разрушения анимации

Мне нужно изменить размер анимированного файла GIF, не разрушая анимацию.

Как я могу сделать это с помощью PHP?

45
riad

если у вас есть доступ к imagemagick, вы можете сделать это:

system("convert big.gif -coalesce coalesce.gif");
system("convert -size 200x100 coalesce.gif -resize 200x10 small.gif");

это, скорее всего, возможно с плагином imagemagick, если у вас нет доступа к системе ()

ПРИМЕЧАНИЕ: это может создать больший размер файла, хотя изображение меньших размеров из-за объединения, по существу, деоптимизации изображения.

UPDATE: Если у вас нет доступа к ImageMagick, вы можете использовать комбинацию из следующих шагов для изменения размера анимированного GIF (при условии, что у вас есть доступ к Gd):

  1. Определите, является ли изображение анимированным GIF: Могу ли я определить анимированные GIF-файлы, используя php и gd? (верхний ответ)
  2. Разделите анимированный GIF на отдельные кадры: http://www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
  3. Изменить размер отдельных кадров: http://www.akemapa.com/2008/07/10/php-Gd-resize-transparent-image-png-gif/
  4. Снова вставьте кадры в анимированный GIF: http://www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html

Это определенно намного интенсивнее, чем маршрут ImageMagick, но это должно быть технически возможно.

Если у вас получилось, поделитесь со всем миром!

58
Jeremy Stanley

Пытаться GDEnhancer (Используйте ImageCraft ). Для этого нужна только библиотека Gd, и она сохраняет анимацию GIF.

11
nut

Вам нужно будет разложить gif на кадры, миниатюру и собрать заново. 

Взгляните на ImageMagick и этот урок .

10
cherouvim

Я пробовал многочисленные примеры изменения размера анимированных GIF-файлов с помощью модуля Imagick PHP, но ни один из них не помог мне .. Затем, после некоторого времени отладки, я обнаружил реальную проблему: анимация была потеряна при сохранении изображения в диск, $animation->writeImage($file_dst); или $animation->writeImages($file_dst, true);

Я изменил его на file_put_contents($file_dst, $animation->getImagesBlob()); И большинство примеров сразу начали работать.

Надеюсь, это поможет кому-то.

4
Antony Harder

Пример на http://www.php.net/manual/en/imagick.coalesceimages.php изменит размер вашего GIF при сохранении времени кадра. Что-то большинство других примеров не делают.

Другие примеры rebuild gif, в то время как этот позволяет вам модифицировать кадры изображения.

4
Matt Crossley

Если у вас установлен ImageMagick, вы можете использовать один вызов convert:

system("convert big.gif -coalesce -repage 0x0 -resize 200x100 -layers Optimize small.gif");
3
Alec Jacobson

Я думаю, что у меня есть это в сумке.

Это решение ни в коем случае не является идеальным и содержит некоторую грубую силу здесь и там, но я смог добавить свой сценарий изменения размера изображений на основе Gd/PHP с достаточной функциональностью для поддержки анимации.

Решение в значительной степени основано на превосходных бесплатных библиотеках Ласло Зсиди - http://www.phpclasses.org/browse/author/283569.html

Вы можете ознакомиться с краткой демонстрацией и загрузить исходники с http://forssto.com/gifexample/ (прямая ссылка: http://forssto.com/gifexample/gifanimresize.Zip )

ИЗВЕСТНЫЕ ВОПРОСЫ: 

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

  • Частота кадров - по неизвестной причине Класс GifEncoder не принимает Во внимание указанные частоты кадров Мне нужно разобраться Это позже.

  • Я нашел один gif-файл из моего набора Тестов, которые каким-то образом имели разные кадры И анимация Не работала правильно. Еще какие-то Отладки делать потом.

2
Tommi Forsström

просто создайте 3 имени папки 1.frame_output 2.images 3.resized_frame_output и загрузите 2 класса кодировщика и декодера по этой ссылке ниже 1.Загрузите класс "GIFDecoder.class.php" с http: //phpclasses.elib. ru/browse/package/3234.html 2.Скачать класс "GIFEncoder.class.php" из http://phpclasses.betablue.net/browse/package/3163.html

а затем запустите имя сценария как «resize_animator.php», создайте загрузочный html-файл и позвольте сценарию «насладиться».

..сохраните этот скрипт как ..... index.php .......

<html>
<body>
<table width="500" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#CCCCCC">
<tr>
<form action="resize_animator.php" method="post" enctype="multipart/form-data" >
<td>
<table width="100%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF">
<tr>
<td align="center"><font face="Tahoma">SELECT ANIMATED FILE</font> 
<input type="file" name="uploadfile" size="20" accept="image/gif"/>
</td>
</tr>
<tr>
<td align="center"><input type="submit" name="Submit" value="PROCESS ANIMATION" /></td>
</tr>
</table>
</td>
</form>
</tr>
</table>
</body>
</html>

........................ сохранить и этот скрипт как resize_animator.php ............

   <?php

   require "GIFDecoder.class.php";
   include "GIFEncoder.class.php";
   $file_name= $_FILES['uploadfile']['name'];
   $file_ext = substr($file_name, -4);
   $file_size=($_FILES["uploadfile"]["size"] /1024 );
   if($file_ext=='.gif')
    {
 if($file_size > 0 && $file_size < 2000 )
  {
    session_start ( );
        $uploaded_file = $_FILES['uploadfile']['tmp_name'];
        $fp=file_get_contents($uploaded_file);

        if ( $fp )
            {
                $_SESSION['delays'] = Array ( );
                $gif = new GIFDecoder ( $fp );
                $arr = $gif->GIFGetFrames ( );
                $_SESSION [ 'delays' ] = $gif -> GIFGetDelays ( );

                for ( $i = 0; $i < count ( $arr ); $i++ )
                {
                        fwrite ( fopen ( ( $i < 10 ? "frame_output/$i$i_frame.gif" : "frame_output/$i_frame.gif" ), "wb" ), $arr [ $i ] );
                }
          }

        function resize_frames($newwidth,$newheight)
            {
                    $dir=opendir("frame_output/");
                    $i=0;
                    while($imgfile=readdir($dir))
                    {
                         if ($imgfile != "." && $imgfile!="..")
                             {
                                        $imgarray[$i]=$imgfile;
                                        $uploadedfile = "frame_output/".$imgarray[$i];
                                        $src = imagecreatefromgif($uploadedfile);
                                        list($width,$height)=getimagesize($uploadedfile);
                                        $tmp=imagecreatetruecolor($newwidth,$newheight);
                                        imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
                                        $filename = "resized_frame_output/".$imgarray[$i];
                                        imagegif($tmp,$filename,100);
                                        imagedestroy($src);
                                        imagedestroy($tmp);
                                        $i++;
                            }
                    }
                    closedir($dir);

                if ( $dh = opendir ( "resized_frame_output/" ) )
                {
                    while ( false !== ( $dat = readdir ( $dh ) ) )
                    {
                        if ( $dat != "." && $dat != ".." )
                        {
                            $frames [ ] = "resized_frame_output/$dat";
                        }
                    }
                    closedir ( $dh );
                }

            $gif = new GIFEncoder   ( $frames,$_SESSION [ 'delays' ],0, 2, 0, 0, 0,"url" );
            $data = $gif->GetAnimation ( );

            $x='x';
            $y='_';
            $uploaded_file_name= $_FILES['uploadfile']['name'];
            $actual_file_name = substr($uploaded_file_name, 0, -4);
            $file_extention = substr($uploaded_file_name, -4);
            $new_name=$actual_file_name.$y.$newwidth.$x.$newheight.$file_extention ;

            //$output_image_name=$newwidth.$x.$newheight;
            fwrite ( fopen ( "images/$new_name", "wb" ), $data );
            //remove resized frames from folder
            //sleep for 1 second
            // usleep(2000000);
            $dir = 'resized_frame_output/';
            foreach(glob($dir.'*.*') as $v)
                {
                 unlink($v);
                }
        }  // end of function resize_frames


            $gif = new GIFEncoder   ( $frames,$_SESSION [ 'delays' ],0, 2, 0, 0, 0,"url" );
            $data = $gif->GetAnimation ( );

            $x='x';
            $y='_';
            $z='_p';
            $uploaded_file_name= $_FILES['uploadfile']['name'];
            $actual_file_name = substr($uploaded_file_name, 0, -4);
            $file_extention = substr($uploaded_file_name, -4);
            $new_name=$actual_file_name.$y.$newwidth.$x.$newheight.$z.$file_extention ;

            //$output_image_name=$newwidth.$x.$newheight;
            fwrite ( fopen ( "images/$new_name", "wb" ), $data );
            //remove resized frames from folder
            //sleep for 1 second
             //usleep(2000000);
            $dir = 'resized_frame_output/';
            foreach(glob($dir.'*.*') as $v)
                {
                 unlink($v);
                }
        }  // end of function resize_frames

            resize_frames(110,110);
            resize_frames(120,160);
            resize_frames(120,80);
            resize_frames(128,96);
            resize_frames(128,128);
            resize_frames(208,208);
            resize_frames(208,320);

            session_destroy();

            //usleep(200000);

            //remove resized frames from folder
            $dir = 'frame_output/';
            foreach(glob($dir.'*.*') as $v)
                {
                 unlink($v);
                }
      echo "<center><h1>Your Animation processing is compleated.</h1></center>";
      echo "<center><h2><a href=\"index.php\">BACK TO UPLOAD PAGE</h2></center>";
  }  //end of file size checker
else
 {
      echo "<center><h2>You Upload a unfit size image .Upload a file within 2000 KB</h2></center>";
      echo "<center><h2><a href=\"index.php\">BACK TO UPLOAD PAGE</h2></center>";
 }
   } //end of file extention checker
  else
  {
   echo "<center><h2>Uplaod a gif file!</h2></center>";
   echo "<center><h2><a href=\"index.php\">BACK TO UPLOAD PAGE</h2></center>";
  }
  ?>

.......................ДАВАЙ НАСЛАДИМСЯ............

раскомментируйте функцию usleep, чтобы увидеть, что работа происходит в этих папках. Это не обязательно, но я использую ее, чтобы увидеть функциональность.

1
riad

Если у вас нет Imagemagick на вашем сервере, вы можете попробовать это: 

http://www.phpclasses.org/package/7353-PHP-Resize-animations-in-files-of-the-GIF-format.html

Класс изменяет размер GIF-анимации с помощью Gd. Сначала анализирует кадры, затем изменяет их размер, после чего снова компилирует их в один файл без потери времени задержки, методов удаления, таблиц цветов и т.д. 

Попробуйте, и если вы обнаружите ошибку или хотите предложить некоторые варианты оптимизации и т.д., Вы можете воспользоваться форумом класса или оставить комментарий на странице моего сайта. И я отвечу как можно скорее.

1
Taha Paksu

Это все ответы, кроме корыта ImageMagick не работает для меня. Сценарии в ответах до этого все полны ошибок.

Даже установкой ImageMagick было сложно управлять, так что вот мой опыт.

Здесь как установить ImageMagick на windows 7 и xampp 1.7.4.
Примечание: выберите 64 бит (для win7) и при установке оставьте отмеченным параметр «Добавить в системный путь».

А затем следуйте: http://www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick

Я потерял часы на скриптах в этих постах, а ImageMagick и этот урок были успешными за считанные минуты.

И еще одно замечание: на моем веб-сервере по умолчанию установлен ImageMagick, так что, думаю, на большинстве серверов он тоже есть.

1
Sturko

GIF Animation Resizer это простой одноклассный инструмент, который сделает свое дело.

Примечание: Используется временная папка для записи отдельных кадров. Хотя это временные метки фреймов, вам может потребоваться создать уникальную папку, если вы собираетесь использовать ее на сервере, где несколько пользователей будут одновременно изменять размеры GIF-файлов.

1
David Harkness

Я использовал эту функцию:

function gifResize($file_Origin,$file_dest,$percent){       
   $crop_w = 0;
   $crop_h = 0;
   $crop_x = 0;
   $crop_y = 0;
   $image = new Imagick($file_Origin);
   $originalWidth = $image->getImageWidth();
   $originalHeight = $image->getImageHeight();
   $size_w = ($originalWidth*$percent)/100;
   $size_h = ($originalHeight*$percent)/100;
   if(($size_w-$originalWidth)>($size_h-$originalHeight)){
       $s = $size_h/$originalHeight;
       $size_w = round($originalWidth*$s);
       $size_h = round($originalHeight*$s);
   }else{
       $s = $size_w/$originalWidth;
       $size_w = round($originalWidth*$s);
       $size_h = round($originalHeight*$s);
   }       
   $image = $image->coalesceImages();

   foreach ($image as $frame) {
       $frame->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
       $frame->thumbnailImage($size_h, $size_w);
       $frame->setImagePage($size_h, $size_w, 0, 0);
   }
   $imageContent = $image->getImagesBlob();
   $fp = fopen($file_dest,'w');
   fwrite($fp,$imageContent);
   fclose($fp);

}

0
Fernando RIS

Imagecraft - это надежная библиотека PHP Gd и расширение, которое поддерживает анимацию GIF, редактирует и создает изображения в нескольких слоях и поддерживает водяной знак.

0
Waqas Bukhary