完美实现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+dbfile开发小型留言本
Oct 09 PHP
用PHP函数解决SQL injection
Dec 09 PHP
PHP学习笔记之数组篇
Jun 28 PHP
php截取后台登陆密码的代码
May 05 PHP
解析:使用php mongodb扩展时 需要注意的事项
Jun 18 PHP
你可能不知道PHP get_meta_tags()函数
May 12 PHP
ThinkPHP3.1的Widget新用法
Jun 19 PHP
PHP的Yii框架中行为的定义与绑定方法讲解
Mar 18 PHP
thinkPHP3.2.2框架行为扩展及demo示例
Jun 19 PHP
PHP实现的多进程控制demo示例
Jul 22 PHP
PHP时间相关常用函数用法示例
Jun 03 PHP
PHP Trait功能与用法实例分析
Jun 03 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模板的朋友必看的很多个顶级PHP模板引擎比较分析
2008/05/26 PHP
用Php编写注册后Email激活验证的实例代码
2013/03/11 PHP
php页面函数设置超时限制的方法
2014/12/01 PHP
解决ThinkPHP下使用上传插件Uploadify浏览器firefox报302错误的方法
2015/12/18 PHP
CodeIgniter配置之SESSION用法实例分析
2016/01/19 PHP
PHP的curl函数的用法总结
2019/02/14 PHP
“不能执行已释放的Script代码”错误的原因及解决办法
2007/09/09 Javascript
node.js中的url.parse方法使用说明
2014/12/10 Javascript
javascript中Date对象的getDay方法使用指南
2014/12/22 Javascript
JavaScript中iframe实现局部刷新的几种方法汇总
2016/01/06 Javascript
详解JS面向对象编程
2016/01/24 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
利用Node.js制作爬取大众点评的爬虫
2016/09/22 Javascript
javascript中的深复制详解及实例分析
2016/12/29 Javascript
使用JavaScript判断用户输入的是否为正整数(两种方法)
2017/02/05 Javascript
在vue-cli中组件通信的方法
2017/12/16 Javascript
Vue组件化开发思考
2018/02/02 Javascript
django使用channels2.x实现实时通讯
2018/11/28 Javascript
jquery实现两个div中的元素相互拖动的方法分析
2020/04/05 jQuery
使用Vue实现一个树组件的示例
2020/11/06 Javascript
python中使用urllib2获取http请求状态码的代码例子
2014/07/07 Python
基于pip install django失败时的解决方法
2018/06/12 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
python 爬取马蜂窝景点翻页文字评论的实现
2020/01/20 Python
python实现简单学生信息管理系统
2020/04/09 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
草莓网化妆品澳大利亚站:Strawberrynet AU
2017/12/18 全球购物
eBay英国购物网站:eBay.co.uk
2019/06/19 全球购物
用Python写一个for循环的例子
2016/07/19 面试题
篮球赛口号
2014/06/18 职场文书
俞敏洪一分钟演讲稿
2014/08/26 职场文书
2014年度党员自我评议
2014/09/13 职场文书
个人四风问题整改措施思想汇报
2014/10/04 职场文书
创业计划书之少年玩具店
2019/09/05 职场文书
Java面试题冲刺第十六天--消息队列
2021/08/07 面试题
零基础学java之方法的定义与调用详解
2022/04/10 Java/Android