完美实现GIF动画缩略图的php代码


Posted in PHP onJanuary 02, 2011

下面通过一个取自CS警匪游戏的GIF动画来说明问题:

完美实现GIF动画缩略图的php代码

GIF动画图片:old.gif

为了让问题更加清晰,我们先还原动画各帧:

选择一:用PHP中的Imagick模块:

<?php 
$image = new Imagick('old.gif'); 
$i = 0; 
foreach ($image as $frame) { 
$frame->writeImage('old_' . $i++ . '.gif'); 
} 
?>

选择二:用ImageMagick提供的convert命令:
shell> convert old.gif old_%d.gif

结果得到GIF动画各帧示意图如下所示:

完美实现GIF动画缩略图的php代码

GIF动画各帧示意图

可以明显的看到,GIF动画为了压缩,会以第一帧为模板,其余各帧按照适当的偏移量依次累加,并只保留不同的像素,结果是导致各帧尺寸不尽相同,为缩略图造成障碍。

下面看看如何用PHP中的Imagick模块来完美实现GIF动画缩略图:

<?php 
$image = new Imagick('old.gif'); 
$image = $image->coalesceImages(); 
foreach ($image as $frame) { 
$frame->thumbnailImage(50, 50); 
} 
$image = $image->optimizeImageLayers(); 
$image->writeImages('new.gif', true); 
?>

代码里最关键的是coalesceimages方法,它确保各帧尺寸一致,用手册里的话来说就是:

Composites a set of images while respecting any page offsets and disposal methods. GIF, MIFF, and MNG animation sequences typically start with an image background and each subsequent image varies in size and offset. Returns a new Imagick object where each image in the sequence is the same size as the first and composited with the next image in the sequence.

同时要注意optimizeImageLayers方法,它删除重复像素内容,用手册里的话来说就是:

Compares each image the GIF disposed forms of the previous image in the sequence. From this it attempts to select the smallest cropped image to replace each frame, while preserving the results of the animation.

BTW:如果要求更完美一点,可以使用quantizeImages方法进一步压缩。

注意:不管是coalesceimages,还是optimizeImageLayers,都是返回新的Imagick对象!

如果你更习惯操作shell的话,那么可以这样实现GIF动画缩略图:

shell> convert old.gif -coalesce -thumbnail 50x50 -layers optimize new.gif

生成的new.gif如下:

 

完美实现GIF动画缩略图的php代码

new.gif

有个细节问题:convert版本会比php版本小一些,这是API实现不一致所致。

另外,如果缩略图尺寸不符合原图比例,为了避免变形,还要考虑裁剪或者是补白,由于本文主要讨论GIF动画缩略图的特殊性,就不再继续讨论这些问题了,有兴趣的自己搞定吧。

PHP 相关文章推荐
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
Jan 27 PHP
PHP中获取文件扩展名的N种方法小结
Feb 27 PHP
php中定时计划任务的实现原理
Jan 08 PHP
thinkPHP连接sqlite3数据库的实现方法(附Thinkphp代码生成器下载)
May 27 PHP
PHP多维数组元素操作类的方法
Nov 14 PHP
PHP中让json_encode不自动转义斜杠“/”的方法
Feb 28 PHP
Mac系统下安装PHP Xdebug
Mar 30 PHP
php用xpath解析html的代码实例讲解
Feb 14 PHP
wordpress自定义标签云与随机获取标签的方法详解
Mar 22 PHP
PHP进阶学习之反射基本概念与用法分析
Jun 18 PHP
thinkphp框架表单数组实现图片批量上传功能示例
Apr 04 PHP
关于PHP求解三数之和问题详析
Nov 09 PHP
php实现无限级分类实现代码(递归方法)
Jan 01 #PHP
php下尝试使用GraphicsMagick的缩略图功能
Jan 01 #PHP
PHP读取XML值的代码(推荐)
Jan 01 #PHP
PHP中simplexml_load_string函数使用说明
Jan 01 #PHP
php xml 入门学习资料
Jan 01 #PHP
PHP+SQL 注入攻击的技术实现以及预防办法
Dec 29 #PHP
解决PHP在DOS命令行下却无法链接MySQL的技术笔记
Dec 29 #PHP
You might like
php输出全球各个时区列表的方法
2015/03/31 PHP
PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
2016/05/22 PHP
PHP示例演示发送邮件给某个邮箱
2019/04/03 PHP
textarea 控制输入字符字节数(示例代码)
2013/12/27 Javascript
js与jquery获取父元素,删除子元素的两种不同方法
2014/01/09 Javascript
jQuery幻灯片带缩略图轮播效果代码分享
2015/08/17 Javascript
angularjs学习笔记之三大模块(modal,controller,view)
2015/09/26 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
nodejs如何获取时间戳与时间差
2016/08/03 NodeJs
动态生成的DOM不会触发onclick事件的原因及解决方法
2016/08/06 Javascript
使用proxy实现一个更优雅的vue【推荐】
2018/06/19 Javascript
vue v-model实现自定义样式多选与单选功能
2018/07/05 Javascript
微信小程序开发之自定义tabBar的实现
2018/09/06 Javascript
vue单页面实现当前页面刷新或跳转时提示保存
2018/11/02 Javascript
详解微信小程序框架wepy踩坑记录(与vue对比)
2019/03/12 Javascript
NodeJs操作MongoDB教程之分页功能以及常见问题
2019/04/09 NodeJs
vue实现数字滚动效果
2020/06/29 Javascript
[02:39]DOTA2英雄基础教程 极限穿梭编织者
2013/12/05 DOTA
浅析Python装饰器以及装饰器模式
2018/05/28 Python
pygame实现俄罗斯方块游戏
2018/06/26 Python
在IPython中进行Python程序执行时间的测量方法
2018/11/01 Python
Python同步遍历多个列表的示例
2019/02/19 Python
Python实现判断一个整数是否为回文数算法示例
2019/03/02 Python
Django框架实现分页显示内容的方法详解
2019/05/10 Python
Python pandas自定义函数的使用方法示例
2019/11/20 Python
python实现超级马里奥
2020/03/18 Python
Python Json数据文件操作原理解析
2020/05/09 Python
详解CSS3中字体平滑处理和抗锯齿渲染
2017/03/29 HTML / CSS
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
中国电子产品批发商/跨境电商/外贸网:Sunsky-online
2020/04/20 全球购物
回门宴父母答谢词
2014/01/26 职场文书
CAD制图设计师自荐信
2014/01/29 职场文书
宣传委员竞选稿
2015/11/19 职场文书
创业计划书之健康营养产业
2019/10/15 职场文书
golang连接MySQl使用sqlx库
2022/04/14 Golang
mysql5.5中文乱码问题解决的有用方法
2022/05/30 MySQL