完美实现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 simplexmlElement操作xml的命名空间实现代码
Jan 04 PHP
PHP图片自动裁切应付不同尺寸的显示
Oct 16 PHP
php中文繁体和简体相互转换的方法
Mar 21 PHP
基于php的微信公众平台开发入门实例
Apr 15 PHP
UPUPW 更新 64 位 Apache 系列 PHP 7.0 正式版
Dec 08 PHP
PHP使用socket发送HTTP请求的方法
Feb 14 PHP
php while循环控制的简单实例
May 30 PHP
PHP读取并输出XML文件数据的简单实现方法
Dec 22 PHP
php strftime函数的详细用法
Jun 21 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
Feb 27 PHP
php 多个变量指向同一个引用($b = &amp;$a)用法分析
Nov 13 PHP
Thinkphp框架+Layui实现图片/文件上传功能分析
Feb 07 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.MVC的模板标签系统(四)
2006/09/05 PHP
10条PHP编程习惯助你找工作
2008/09/29 PHP
PHP合并数组+与array_merge的区别分析
2010/08/01 PHP
检测png图片是否完整的php代码
2010/09/06 PHP
PHP异步调用socket实现代码
2012/01/12 PHP
PHP实现支付宝即时到账功能
2016/12/21 PHP
js实现运行代码需要刷新的解决方法
2007/08/18 Javascript
EXT窗口Window及对话框MessageBox
2011/01/27 Javascript
js获取控件位置以及不同浏览器中的差别介绍
2013/08/08 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
JavaScript动态检验密码强度的实现方法
2016/11/09 Javascript
学习vue.js条件渲染
2016/12/03 Javascript
jQuery设置图片等比例缩小的方法
2017/04/29 jQuery
vue事件修饰符和按键修饰符用法总结
2017/07/25 Javascript
Vue开发之封装分页组件与使用示例
2019/04/25 Javascript
Nest.js环境变量配置与序列化详解
2021/02/21 Javascript
Python中使用不同编码读写txt文件详解
2015/05/28 Python
分享python数据统计的一些小技巧
2016/07/21 Python
python实现字典(dict)和字符串(string)的相互转换方法
2017/03/01 Python
举例讲解Python常用模块
2019/03/08 Python
利用Python小工具实现3秒钟将视频转换为音频
2019/10/29 Python
利用CSS3实现开门效果实例源码
2016/08/22 HTML / CSS
浅谈HTML5新增及移除的元素
2016/06/27 HTML / CSS
Whittard官方海外旗舰店:英国百年茶叶品牌
2018/02/22 全球购物
美国医疗用品、医疗设备和家庭保健用品商店:Medical Supply Depot
2018/07/08 全球购物
会计找工作求职信范文
2013/12/09 职场文书
《盘古开天地》教学反思
2014/02/28 职场文书
充分就业社区汇报材料
2014/05/07 职场文书
教师党员先进性教育自我剖析材料思想汇报
2014/09/24 职场文书
房屋产权证明书
2014/10/15 职场文书
大学生自我评价范文
2015/03/03 职场文书
2015年城管个人工作总结范文
2015/04/20 职场文书
2015年度合同管理工作总结
2015/05/22 职场文书
高三数学复习备考教学反思
2016/02/18 职场文书
协议书格式模板
2016/03/24 职场文书