web-dev-qa-db-fra.com

Redimensionner le fichier GIF animé sans détruire l'animation

Je dois redimensionner un fichier GIF animé sans détruire l'animation.

Comment puis-je le faire en utilisant PHP?

45
riad

si vous avez un accès imagemagick, vous pouvez faire ceci:

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

c'est probablement possible avec le plugin imagemagick si vous n'avez pas d'accès system ()

REMARQUE: ceci peut créer une taille de fichier plus importante bien qu'une image de plus petite dimension en raison de la fusion essentiellement de la désoptimisation de l'image.

UPDATE: Si vous n'avez pas d'accès ImageMagick, vous devriez pouvoir combiner les étapes suivantes pour redimensionner un gif animé (en supposant que vous ayez accès à Gd):

  1. Détecter si l'image est un gif animé: Puis-je détecter des gifs animés en utilisant php et gd? (réponse haute)
  2. Divisez le gif animé en images individuelles: http://www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
  3. Redimensionnez les cadres individuels: http://www.akemapa.com/2008/07/10/php-Gd-resize-transparent-image-png-gif/
  4. Recomposez les images dans un gif animé à nouveau: http://www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html

C'est certainement beaucoup plus intensif que la route ImageMagick, mais cela devrait être techniquement possible.

Si vous le faites fonctionner, s'il vous plaît partager avec le monde!

58
Jeremy Stanley

Essayer GDEnhancer (Utilisez ImageCraft ). Il n'a besoin que de Gd Library, et garde l'animation gif

11
nut

Vous auriez besoin de décomposer le gif en images, vignettes et réassembler. 

Regardez ImageMagick et ce tutoriel .

10
cherouvim

J'ai essayé de nombreux exemples de redimensionnement de GIF animés avec le module Imagick PHP, mais aucun d'entre eux ne fonctionnait pour moi . Disque, par $animation->writeImage($file_dst); ou $animation->writeImages($file_dst, true);

Je l'ai changée en file_put_contents($file_dst, $animation->getImagesBlob()); Et la plupart des exemples ont commencé à fonctionner immédiatement.

J'espère que ça aide quelqu'un.

4
Antony Harder

L'exemple de http://www.php.net/manual/fr/imagick.coalesceimages.php redimensionnera votre gif tout en conservant la synchronisation de votre cadre. Ce que la plupart des autres exemples ne font pas.

D'autres exemples reconstruisent le gif alors que celui-ci vous permet de modifier les cadres de l'image.

4
Matt Crossley

Si ImageMagick est installé, vous pouvez utiliser un seul appel à convert:

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

Je pense que j'ai ceci dans le sac.

Cette solution n’est en aucun cas parfaite et contient un peu de force brutale ici et là, mais j’ai été en mesure d’ajouter mon script de redimensionnement d’image basé sur Gd/PHP avec suffisamment de fonctionnalités pour prendre en charge les animations.

La solution est largement basée sur les excellentes bibliothèques gratuites de László Zsidi - http://www.phpclasses.org/browse/author/283569.html

Vous pouvez consulter une démonstration rapide et télécharger les sources depuis http://forssto.com/gifexample/ (lien direct: http://forssto.com/gifexample/gifanimresize.Zip )

PROBLÈMES CONNUS: 

  • Prise en charge de la transparence - il serait facile d'ajouter une solution à cette solution, mais, comme je n'ai pas immédiatement besoin de cela, je m'arrête ici.

  • Fréquence de trame - pour une raison inconnue La classe GifEncoder ne parvient pas à prendre en compte Les cadences de prise de vue Spécifiées. J'aurai besoin de regarder plus tard.

  • J'ai trouvé un fichier gif dans mon ensemble De tests qui comportaient en quelque sorte des images de taille Différentes et l'animation Ne fonctionnait pas correctement. Il reste encore du débogage à faire.

2
Tommi Forsström

juste creat 3 nom du dossier 1.frame_output 2.images 3.resized_frame_output et téléchargez 2 codeurs et décodeurs à partir du lien ci-dessous 1.Téléchargez la classe "GIFDecoder.class.php" de http: //phpclasses.elib. com/browse/package/3234.html 2.Téléchargez la classe "GIFEncoder.class.php" à partir de http://phpclasses.betablue.net/browse/package/3163.html

puis exécutez le nom du script en tant que "resize_animator.php", créez un fichier html de téléchargement et laissez profiter du script.

..enregistrez ce script sous le nom ..... 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>

........................ enregistrez et ce script sous le nom de 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 INJOY ............

décommentez la fonction usleep pour voir le travail se dérouler dans ces folder.its pas nécessaire mais je l'utilise pour voir la fonctionnalité.

1
riad

Si vous n'avez pas Imagemagick sur votre serveur, essayez ceci: 

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

La classe redimensionne les animations GIF avec Gd. Il analyse d'abord les images, puis les redimensionne, après quoi il les compile à nouveau dans un fichier unique sans perdre ses délais, ses méthodes d'élimination, ses tables de couleurs, etc. 

Essayez et si vous trouvez un bogue ou si vous souhaitez suggérer des optimisations, etc., vous pouvez utiliser le forum de la classe ou laisser un commentaire sur la page de mon site Web. Et je vais répondre à cette question dès que possible.

1
Taha Paksu

Ceci toutes les réponses sauf par le biais d'ImageMagick n'ont pas fonctionné pour moi. Les scripts dans les réponses avant ceci sont tous pleins d'erreurs.

Même installer ImageMagick était difficile à gérer alors voici mon expérience.

Voici comment installer ImageMagick sur Windows 7 et xampp 1.7.4.
Note: Choisissez 64 bits (pour win7), et lors de l'installation laissez coché l'option "Ajouter au chemin du système".

Et puis suivez: http://www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick

J'ai perdu des heures sur les scripts de ces articles, et ImageMagick et ce tutoriel ont réussi en quelques minutes.

Et encore une remarque: mon serveur Web a ImageMagick par défaut, donc je suppose que la plupart des serveurs l’ont aussi.

1
Sturko

GIF Animation Resizer est un outil simple à une classe qui fera l'affaire.

Note: Il utilise un dossier temporaire pour écrire les images séparées. Pendant qu’il horodate les images, vous devrez peut-être créer un dossier unique si vous souhaitez l’utiliser sur un serveur où plusieurs utilisateurs redimensionneront les fichiers GIF en même temps.

1
David Harkness

J'ai utilisé cette fonction:

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 est une bibliothèque et une extension Gd PHP fiables qui conserve l’animation GIF, modifie et compose les images en plusieurs couches et prend en charge les filigranes.

0
Waqas Bukhary