完美实现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 相关文章推荐
关于session在PHP5的配置文件中的详细设置参数说明
Apr 20 PHP
php数组去重复数据示例
Feb 25 PHP
php实现快速排序的三种方法分享
Mar 12 PHP
浅谈Eclipse PDT调试PHP程序
Jun 09 PHP
PHP中mysql_field_type()函数用法
Nov 24 PHP
PHP中实现获取IP和地理位置类分享
Feb 10 PHP
php基于Snoopy解析网页html的方法
Jul 09 PHP
php数组分页实现方法
Apr 30 PHP
php微信公众号开发(3)php实现简单微信文本通讯
Dec 15 PHP
Ajax中的JSON格式与php传输过程全面解析
Nov 14 PHP
不常用但很实用的PHP预定义变量分析
Jun 25 PHP
ThinkPHP5&amp;5.1实现验证码的生成、使用及点击刷新功能示例
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 session处理的定制
2009/03/16 PHP
PHP Class&amp;Object -- PHP 自排序二叉树的深入解析
2013/06/25 PHP
php实现分页显示
2015/11/03 PHP
PHP实现原生态图片上传封装类方法
2016/11/08 PHP
PHP中通过getopt解析GNU C风格命令行选项
2019/11/18 PHP
JavaScript格式化数字的函数代码
2010/11/30 Javascript
JavaScript实现按照指定长度为数字前面补零输出的方法
2015/03/19 Javascript
js限制input标签中只能输入中文
2015/06/26 Javascript
Nodejs Stream 数据流使用手册
2016/04/17 NodeJs
JavaScript的String字符串对象常用操作总结
2016/05/26 Javascript
js判断某个字符出现的次数的简单实例
2016/06/03 Javascript
原生js封装自定义滚动条
2017/03/24 Javascript
vue的基本用法与常见指令
2017/08/15 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
2019/01/30 Javascript
vue实现搜索过滤效果
2019/05/28 Javascript
五分钟搞懂Vuex实用知识(小结)
2019/08/12 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
基于Ionic3实现选项卡切换并重新加载echarts
2020/09/24 Javascript
js前端对于大量数据的展示方式及处理方法
2020/12/02 Javascript
[03:24][TI9纪实] Dota奶爸
2019/08/22 DOTA
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
2014/07/04 Python
Python中多线程thread与threading的实现方法
2014/08/18 Python
Python 线性回归分析以及评价指标详解
2020/04/02 Python
python绘制趋势图的示例
2020/09/17 Python
美国真皮手袋品牌:GiGi New York
2017/03/10 全球购物
特步官方商城:Xtep
2017/03/21 全球购物
荷兰音乐会和音乐剧门票订购网站:Topticketshop
2019/08/27 全球购物
考博自荐信
2013/10/25 职场文书
工程管理专业个人求职信范文
2013/12/07 职场文书
工作疏忽检讨书
2014/01/25 职场文书
《乌塔》教学反思
2014/02/17 职场文书
《七颗钻石》教学反思
2014/02/28 职场文书
调任通知
2015/04/21 职场文书
公司奖励通知
2015/04/21 职场文书
职业规划从高考志愿专业选择开始
2019/08/08 职场文书