Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

Если вы заработаете, пожалуйста, поделитесь с миром!

Ответ 2

Попробуйте GDEnhancer (используйте ImageCraft). Ему нужна только библиотека GD, и она поддерживает анимацию gif

Ответ 4

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

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

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

Ответ 5

В примере на http://www.php.net/manual/en/imagick.coalesceimages.php будет изменяться размер вашего gif, сохраняя при этом время вашего фрейма. Что-то большинство других примеров не делают.

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

Ответ 6

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

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

Ответ 7

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

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

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

Вы можете проверить быстрое демо и загрузить источники из http://forssto.com/gifexample/ (прямая ссылка: http://forssto.com/gifexample/gifanimresize.zip)

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

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

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

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

Ответ 8

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

а затем запустите имя script как "resize_animator.php", создайте файл html для загрузки и дайте наслаждаться script.

.. Сохраните этот script как..... 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>

........................ сохранить и этот script как 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>";
  }
  ?>

....................... LETS ENJOY............

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

Ответ 9

Все ответы, кроме 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, поэтому я думаю, что на большинстве серверов есть он.

Ответ 10

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

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

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

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

Ответ 11

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

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

Ответ 12

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

Ответ 13

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

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

}