php 在不破坏动画的情况下调整动画 GIF 文件的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/718491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resize animated GIF file without destroying animation
提问by riad
I need to resize an animated GIF file without destroying the animation.
我需要在不破坏动画的情况下调整动画 GIF 文件的大小。
How can I do it using PHP?
我怎样才能使用 PHP 做到这一点?
回答by Jeremy Stanley
if you have imagemagick access, you can do this:
如果您有 imagemagick 访问权限,则可以执行以下操作:
system("convert big.gif -coalesce coalesce.gif");
system("convert -size 200x100 coalesce.gif -resize 200x10 small.gif");
this is most likely possible with the imagemagick plugin if you don't have system() access
如果您没有 system() 访问权限,这很可能使用 imagemagick 插件
NOTE: this may create a larger filesize though a smaller dimensions image due to coalescing essentially deoptimizing the image.
注意:这可能会创建更大的文件大小,但由于合并本质上会取消优化图像,因此图像尺寸较小。
UPDATE:If you don't have ImageMagick access, you should be able to use a combination of the following steps to resize an animated gif (assuming you have GD access):
更新:如果您没有 ImageMagick 访问权限,您应该能够使用以下步骤的组合来调整动画 gif 的大小(假设您有 GD 访问权限):
- Detect if the image is an animated gif: Can I detect animated gifs using php and gd?(top answer)
- Split the animated gif into individual frames: http://www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
- Resize the individual frames: http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/
- Recomposite the frames into an animated gif again: http://www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html
- 检测图像是否为动画 gif:我可以使用 php 和 gd 检测动画 gif 吗?(最佳答案)
- 将动画 gif 分割成单独的帧:http: //www.phpclasses.org/package/3234-PHP-Split-GIF-animations-into-multiple-images.html
- 调整单个框架的大小:http: //www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/
- 再次将帧重新合成为动画 gif:http: //www.phpclasses.org/package/3163-PHP-Generate-GIF-animations-from-a-set-of-GIF-images.html
This is definitely much more intensive than the ImageMagick route, but it should be technically possible.
这绝对比ImageMagick路线密集得多,但在技术上应该是可行的。
If you get it working, please share with the world!
如果你成功了,请与世界分享!
回答by nut
Try GDEnhancer(Use ImageCraft). It only need GD Library, and it keep gif animation
尝试GDEnhancer(使用ImageCraft)。它只需要 GD 库,并保留 gif 动画
回答by cherouvim
You would need to decompose the gif into frames, thumbnail and re-assemble.
您需要将 gif 分解为框架、缩略图并重新组装。
Have a look at ImageMagickand this tutorial.
看看ImageMagick和本教程。
回答by Antony Harder
I have tried numerous examples of resizing animated GIFs with Imagick PHP module, but none of them worked for me.
Then after some debugging time at last I found the actual issue: the animation was lost upon saving image to disk, by $animation->writeImage($file_dst);or
$animation->writeImages($file_dst, true);
我尝试了许多使用 Imagick PHP 模块调整动画 GIF 大小的示例,但没有一个对我有用。然后经过一些调试时间,我终于发现了实际问题:将图像保存到磁盘时,动画丢失了,$animation->writeImage($file_dst);或者
$animation->writeImages($file_dst, true);
I've changed it to
file_put_contents($file_dst, $animation->getImagesBlob());and most examples started working immediately.
我已将其更改为
file_put_contents($file_dst, $animation->getImagesBlob());大多数示例立即开始工作。
Hope it helps someone.
希望它可以帮助某人。
回答by Matt Crossley
The example on http://www.php.net/manual/en/imagick.coalesceimages.phpwill resize your gif while retaining your frame timing. Something most of the other examples do not do.
http://www.php.net/manual/en/imagick.coalesceimages.php上的示例将调整您的 gif 大小,同时保留您的帧时间。大多数其他示例没有做的事情。
Other examples rebuildthe gif while this one allows you to modifythe frames of the image.
其他示例重建gif,而这个示例允许您修改图像的帧。
回答by Alec Jacobson
If you have ImageMagick installed then you can use a single call to convert:
如果您安装了 ImageMagick,那么您可以使用单个调用convert:
system("convert big.gif -coalesce -repage 0x0 -resize 200x100 -layers Optimize small.gif");
回答by Tommi Forsstr?m
I think I've got this in the bag.
我想我已经把这个放在包里了。
This solution is by no means perfect and contains some brute force here and there, but I was able to append my GD / PHP based image resizing script with enough functionality to support animations.
这个解决方案绝不是完美的,并且到处都包含一些蛮力,但我能够附加我的基于 GD/PHP 的图像大小调整脚本,并具有足够的功能来支持动画。
The solution is heavily based on the excellent freeware libraries by László Zsidi - http://www.phpclasses.org/browse/author/283569.html
该解决方案很大程度上基于 László Zsidi 的优秀免费软件库 - http://www.phpclasses.org/browse/author/283569.html
You can check out a quick demo and download the sources from http://forssto.com/gifexample/(direct link: http://forssto.com/gifexample/gifanimresize.zip)
您可以查看快速演示并从http://forssto.com/gifexample/下载源代码(直接链接:http: //forssto.com/gifexample/gifanimresize.zip)
KNOWN ISSUES:
已知的问题:
Transparency support - this would be easy to append to this solution, but as I don't have an immediate need for this, I'm stopping here.
Frame rate - for some unknown reason the GifEncoder class fails to take into account the frame rates specified. I'll need to look into this later.
I did find one gif file from my set of tests that somehow had different sized frames in it and that animation failed to work correctly. Still some debugging to do then.
透明度支持 - 这很容易附加到这个解决方案中,但由于我没有立即需要,我在这里停下来。
帧速率 - 由于某些未知原因,GifEncoder 类未能考虑指定的帧速率。稍后我需要研究一下。
我确实从我的一组测试中找到了一个 gif 文件,其中有不同大小的帧,并且动画无法正常工作。然后还有一些调试要做。
回答by Sturko
This all answers except trough ImageMagick didnt work for me. Scripts in answers before this are all full of errors.
除了低谷 ImageMagick 之外的所有答案对我都不起作用。在此之前的答案中的脚本都充满了错误。
Even installing ImageMagick was difficult to manage so here is my experience.
即使安装 ImageMagick 也很难管理,所以这是我的经验。
Here is how to install ImageMagickon windows 7 and xampp 1.7.4.
Note: Choose 64 bit (for win7), and when installing leave checked the option "Add to system path".
以下是在 Windows 7 和 xampp 1.7.4 上安装 ImageMagick 的方法。
注意:选择 64 位(对于 win7),安装时请勾选“添加到系统路径”选项。
And then follow: http://www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick
然后按照:http: //www.creativearmory.com/tutorials/resize-animated-gifs-with-php-and-imagemagick
I have lost hours on scripts at this posts, and ImageMagick and this tutorial was sucessfull in minutes.
我在这篇文章的脚本上浪费了几个小时,而 ImageMagick 和本教程在几分钟内就成功了。
And one more note: my webserver have ImageMagick by default, so i guess most of servers have it too.
还有一点要注意:我的网络服务器默认有 ImageMagick,所以我猜大多数服务器也有。
回答by Taha Paksu
If you dont have Imagemagick in your server you may want to try this :
如果您的服务器中没有 Imagemagick,您可能想试试这个:
http://www.phpclasses.org/package/7353-PHP-Resize-animations-in-files-of-the-GIF-format.html
http://www.phpclasses.org/package/7353-PHP-Resize-animations-in-files-of-the-GIF-format.html
The class is resizing GIF animations with GD. First parses the frames, then resizes them, after that it compiles them again into single file without losing its delay times,disposal methods, color tables etc.
该课程正在使用 GD 调整 GIF 动画的大小。首先解析帧,然后调整它们的大小,然后将它们再次编译为单个文件,而不会丢失延迟时间、处理方法、颜色表等。
Try and if you find a bug or want to suggest some optimizations etc. you can use the class' forum or leave a comment on the page in my website. And I'll answer that ASAP.
尝试一下,如果您发现错误或想提出一些优化建议等,您可以使用班级论坛或在我网站的页面上发表评论。我会尽快回答。
回答by riad
just creat 3 folder name 1.frame_output 2.images 3.resized_frame_output and download 2 encoder and decoder class from this below link 1.Download class "GIFDecoder.class.php" from http://phpclasses.elib.com/browse/package/3234.html2.Download class "GIFEncoder.class.php" from http://phpclasses.betablue.net/browse/package/3163.html
只需创建 3 个文件夹名称 1.frame_output 2.images 3.resized_frame_output 并从以下链接下载 2 个编码器和解码器类 1.从http://phpclasses.elib.com/browse/package下载类“GIFDecoder.class.php” /3234.html2.从http://phpclasses.betablue.net/browse/package/3163.html下载类“GIFEncoder.class.php”
and then run the script name as "resize_animator.php" , creat a upload html file & Let Enjoy the script.
然后运行脚本名称为 "resize_animator.php" ,创建一个上传 html 文件并让我们享受脚本。
..save this script as .....index.php.......
..将此脚本另存为.....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>
........................save and this script as resize_animator.php............
.......... 将此脚本另存为 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............
.....................让我们享受......
uncomment the usleep function to see the work happen into those folders.its not necessary but i use it to see the functionality.
取消注释 usleep 函数以查看这些文件夹中发生的工作。这不是必需的,但我使用它来查看功能。

