在不破坏animation的情况下调整animationGIF文件的大小

我需要调整animationGIF文件的大小而不破坏animation。

我怎样才能使用PHP?

如果你有imagemagick访问,你可以这样做:

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

如果你没有system()访问权限的话,这个imagemagick插件是最有可能的

注意:这可能会创build一个更大的文件大小,但由于聚合实质上使图像最优化,所以尺寸较小的图像。

更新:如果你没有ImageMagick访问,你应该能够使用以下步骤的组合来调整animationgif的大小(假设你有GD访问):

  1. 检测图像是否为animationgif: 我可以使用php和gd检测animationgif吗? (最佳答案)
  2. 将animationGIF分成单独的帧: 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. 再次将框架重新构build为animationGIF: http : //www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html

这肯定比ImageMagick路线要密集得多,但在技术上应该是可行的。

如果你得到它的工作,请与世界分享!

尝试GDEnhancer (使用ImageCraft )。 它只需要GD库,并保持gifanimation

你需要将gif分解成帧,缩略图和重新组装。
看看ImageMagick: http : //php.net/imagick和本教程: http : //www.phpro.org/examples/Thumbnail-From-Animated-GIF.html

我已经尝试过使用Imagick PHP模块调整animationGIF的大量例子,但是没有一个能够为我工作。 然后经过一些debugging,最后我发现了一个实际的问题:在将图像保存到磁盘时,animation丢失了$animation->writeImage($file_dst);$animation->writeImages($file_dst, true);

我把它改成了file_put_contents($file_dst, $animation->getImagesBlob()); 大多数例子都立即开始工作。

希望它可以帮助别人。

http://www.php.net/manual/en/imagick.coalesceimages.php上的例子将调整你的gif,同时保留你的帧时间。; 其他大多数例子都不行。

其他例子重build gif,而这个允许你修改图像的帧。

如果您安装了ImageMagick,那么您可以使用单个调用来convert

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

我想我已经拿到了这个包。

这个解决scheme并不完美,并且在这里和那里包含一些暴力,但是我能够附加我的基于GD / PHP的图像调整脚本足够的function来支持animation。

该解决scheme主要基于LászlóZsidi的优秀免费软件库 – http://www.phpclasses.org/browse/author/283569.html

您可以查看快速演示,并从http://forssto.com/gifexample/下载源代码(直接链接:; http : //forssto.com/gifexample/gifanimresize.zip )

已知的问题:

  • 支持透明度 – 这将很容易附加到这个解决scheme,但由于我没有立即需要这个,我在这里停下来。

  • 帧速率 – 由于某些未知的原因,GifEncoder类未能考虑指定的帧速率。 我需要稍后再研究。

  • 我确实从我的一组testing中find了一个gif文件,它有不同大小的帧,并且animation无法正常工作。 还有一些debugging要做。

只需创build3文件夹名称1.frame_output 2.images 3.resized_frame_output并从下面的链接下载2编码器和解码器类链接1.从http://phpclasses.elib.com/browse/package下载类“GIFDecoder.class.php”; /3234.html 2.从http://phpclasses.betablue.net/browse/package/3163.html下载类“GIFEncoder.class.php”;

然后运行脚本名称为“resize_animator.php”,创build一个上传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>"; } ?> 

……………………让我们享受…………

取消注释hibernatefunction,看看工作发生在这些folders.its不必要,但我用它来看function。

如果你没有Imagemagick在你的服务器上,你可能想试试这个:

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

该类正在调整GD的GIFanimation。 首先parsing框架,然后resize,然后将其重新编译为单个文件,而不会丢失其延迟时间,处理方法,颜色表等。

尝试,如果你发现一个错误,或者想build议一些优化等,你可以使用类的论坛,或在我的网站页面留言。 我会尽快回答。

除了槽ImageMagick这一切的答案没有为我工作。 在这之前的答案脚本都是错误的。

即使安装ImageMagick也很难pipe理,所以这是我的经验。

这里是如何在Windows 7和xampp 1.7.4上安装ImageMagick 。
注意 :select64位(对于win7),安装时选中“添加到系统path”选项。

然后按照: http : //www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick

在这篇文章中,我已经损失了几个小时的脚本,ImageMagick和这个教程在几分钟内就成功了。

还有一个注意:我的web服务器默认情况下有ImageMagick,所以我想大多数的服务器也是这样。

GIFanimation调整器是一个简单的一类工具,将做的伎俩。

注意:它使用临时文件夹来写出单独的帧。 如果您打算在多个用户同时调整GIF大小的服务器上使用此function,则可能需要创build唯一的文件夹。

Imagecraft是一个可靠的PHP GD库和扩展,保持GIFanimation,编辑和合成图像在多个层次,并支持水印。

我使用这个function:

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

}