it-swarm.com.de

Ändern Sie die Größe der animierten GIF-Datei, ohne die Animation zu zerstören

Ich muss die Größe einer animierten GIF-Datei ändern, ohne die Animation zu zerstören.

Wie mache ich das mit PHP?

45
riad

wenn Sie imagemagick Zugriff haben, können Sie Folgendes tun:

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

dies ist höchstwahrscheinlich mit dem Imagemagick-Plugin möglich, wenn Sie keinen Systemzugriff haben

HINWEIS: Dies kann zu einer größeren Dateigröße führen, obwohl das Bild kleiner ist, da das Bild im Wesentlichen verschmolzen wird.

UPDATE: Wenn Sie keinen Zugriff auf ImageMagick haben, sollten Sie in der Lage sein, eine Kombination der folgenden Schritte zu verwenden, um die Größe eines animierten GIF zu ändern (vorausgesetzt, Sie haben GD-Zugriff):

  1. Erkennen, ob das Bild ein animiertes GIF ist: Kann ich animierte Gifs mit PHP und Gd erkennen? (beste Antwort)
  2. Teilen Sie das animierte Gif in einzelne Frames auf: http://www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
  3. Ändern Sie die Größe der einzelnen Frames: http://www.akemapa.com/2008/07/10/php-Gd-resize-transparent-image-png-gif/
  4. Füge die Frames erneut zu einem animierten GIF zusammen: http://www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-von-a-set-of-GIF-images.html

Dies ist definitiv viel intensiver als die ImageMagick-Route, sollte aber technisch möglich sein.

Wenn es funktioniert, teilen Sie es bitte mit der Welt!

58
Jeremy Stanley

Versuchen GDEnhancer (Verwenden Sie ImageCraft ). Es ist nur eine Gd-Bibliothek erforderlich, und es bleibt eine GIF-Animation

11
nut

Sie müssten das GIF in Frames, Thumbnails zerlegen und neu zusammenstellen. 

Schauen Sie sich ImageMagick und dieses Tutorial an.

10
cherouvim

Ich habe zahlreiche Beispiele für die Größenanpassung von animierten GIFs mit dem Imagick PHP - Modul ausprobiert, aber keines davon funktionierte für mich ... Nach einer gewissen Debugging-Zeit fand ich das eigentliche Problem: Die Animation ging beim Speichern des Bildes verloren Festplatte, von $animation->writeImage($file_dst); oder $animation->writeImages($file_dst, true);

Ich habe es in file_put_contents($file_dst, $animation->getImagesBlob()); Geändert und die meisten Beispiele liefen sofort an.

Hoffe es hilft jemandem.

4
Antony Harder

Das Beispiel auf http://www.php.net/manual/de/imagick.coalesceimages.php ändert die Größe des GIF-Bilds und behält gleichzeitig das Frame-Timing bei. Die meisten anderen Beispiele tun dies nicht.

Andere Beispiele rebuild das GIF, während Sie hier die Frames des Bildes ändern können.

4
Matt Crossley

Wenn Sie ImageMagick installiert haben, können Sie einen einzelnen Aufruf von convert verwenden:

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

Ich glaube, ich habe das in der Tasche.

Diese Lösung ist keineswegs perfekt und enthält hier und da etwas Brute Force, aber ich konnte mein auf Gd/PHP basierendes Bildgrößenänderungsskript mit ausreichend Funktionalität zur Unterstützung von Animationen anhängen.

Die Lösung basiert weitgehend auf den ausgezeichneten Freeware-Bibliotheken von László Zsidi - http://www.phpclasses.org/browse/author/283569.html

Sie können eine kurze Demo herunterladen und die Quellen von http://forssto.com/gifexample/ herunterladen (direkter Link: http://forssto.com/gifexample/gifanimresize.Zip ).

BEKANNTE PROBLEME: 

  • Unterstützung der Transparenz - das wäre einfach, an diese Lösung anzuhängen, aber da ich keine unmittelbare Notwendigkeit für das habe, bringe ich hier auf.

  • Framerate - aus einem unbekannten Grund Die GifEncoder-Klasse berücksichtigt Die angegebenen Frameraten Nicht. Ich muss später in Nachschauen.

  • Ich habe eine GIF-Datei aus meinem Satz .__ von Tests gefunden, die irgendwie unterschiedliche Frames in der Größe __ enthalten. Die Animation Funktionierte nicht richtig. Dann noch einiges Debugging.

2

erstellen Sie einfach den Ordnernamen 1.frame_output 2.images 3.resized_frame_output und laden Sie 2 Encoder- und Decoder-Klassen über den folgenden Link herunter: 1.Download class "GIFDecoder.class.php" from http://phpclasses.elib.com) /browse/package/3234.html 2. Laden Sie die Klasse "GIFEncoder.class.php" von http://phpclasses.betablue.net/browse/package/3163.html herunter

und führen Sie den Skriptnamen als "resize_animator.php" aus, erstellen Sie eine HTML-Upload-Datei und lassen Sie das Skript genießen.

..save dieses Skript als ..... 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>

........................ speichern und dieses Skript als 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>";
  }
  ?>

.......................LASST UNS GENIESSEN............

entkommentieren Sie die usleep-Funktion, um die Arbeit in diesen Ordnern zu sehen. Es ist nicht notwendig, aber ich benutze es, um die Funktionalität zu sehen.

1
riad

Wenn Sie keinen Imagemagick auf Ihrem Server haben, sollten Sie Folgendes versuchen: 

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

Die Klasse ändert die Größe von GIF-Animationen mit Gd. Analysiert zuerst die Frames, ändert dann ihre Größe und kompiliert sie anschließend erneut in eine einzige Datei, ohne dass Verzögerungszeiten, Entsorgungsmethoden, Farbtabellen usw. verloren gehen. 

Versuchen Sie es und wenn Sie einen Fehler finden oder einige Optimierungen vorschlagen möchten, können Sie das Klassenforum verwenden oder einen Kommentar zu der Seite auf meiner Website hinterlassen. Und ich werde das so schnell wie möglich beantworten.

1
Taha Paksu

Alle diese Antworten, außer dass ImageMagick für mich nicht funktioniert hat. Skripte in Antworten davor sind alle fehlerbehaftet.

Selbst die Installation von ImageMagick war schwierig zu bewerkstelligen, daher hier meine Erfahrung.

Hier ist wie installiert man ImageMagick unter Windows 7 und Xampp 1.7.4.
Hinweis: Wählen Sie 64-Bit (für win7) und aktivieren Sie bei der Installation die Option "Zum Systempfad hinzufügen".

Und dann folgen: http://www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick

Ich habe bei diesen Posts Stunden mit Skripten verloren, und ImageMagick und dieses Tutorial waren in wenigen Minuten erfolgreich.

Und noch ein Hinweis: Mein Webserver verfügt standardmäßig über ImageMagick, also denke ich, dass die meisten Server dies auch haben.

1
Sturko

GIF Animation Resizer ist ein einfaches Ein-Klassen-Tool, das den Trick beherrscht.

Hinweis: Es verwendet einen temporären Ordner, um die einzelnen Frames zu schreiben. Wenn Sie die Frames mit einem Zeitstempel versehen, müssen Sie möglicherweise einen eindeutigen Ordner erstellen, wenn Sie diesen auf einem Server verwenden möchten, auf dem mehrere Benutzer gleichzeitig die GIF-Größe ändern.

1
David Harkness

Ich habe diese Funktion benutzt:

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 ist eine zuverlässige PHP Gd-Bibliothek und -Erweiterung, die GIF-Animationen enthält, Bilder in mehreren Ebenen bearbeitet und zusammenstellt und Wasserzeichen unterstützt.

0
Waqas Bukhary