完美实现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和XSL stylesheets转换XML文档
Oct 09 PHP
优化PHP代码的53条建议
Mar 27 PHP
Php中文件下载功能实现超详细流程分析
Jun 13 PHP
php中使用redis队列操作实例代码
Feb 07 PHP
探讨如何在php168_cms中提取验证码
Jun 08 PHP
php操作mysql数据库的基本类代码
Feb 25 PHP
一个图片地址分解程序(用于PHP小偷程序)
Aug 23 PHP
PHP使用MPDF类生成PDF的方法
Dec 08 PHP
php操作xml并将其插入数据库的实现方法
Sep 08 PHP
PHP版微信小店接口开发实例
Nov 12 PHP
Laravel5.1框架注册中间件的三种场景详解
Jul 09 PHP
TP5框架实现的数据库备份功能示例
Apr 05 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
递归列出所有文件和目录
2006/10/09 PHP
PHP中去掉字符串首尾空格的方法
2012/05/19 PHP
php中计算未知长度的字符串哪个字符出现的次数最多的代码
2012/08/14 PHP
php文件上传的简单实例
2013/10/19 PHP
Yii实现自动加载类地图的方法
2015/04/01 PHP
[原创]php使用curl判断网页404(不存在)的方法
2016/06/23 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
2019/10/11 PHP
游戏人文件夹程序 ver 3.0
2006/07/14 Javascript
javascript OFFICE控件测试代码
2009/12/08 Javascript
jQuery-ui中自动完成实现方法
2010/06/10 Javascript
基于jQuery UI CSS Framework开发Widget的经验
2010/08/21 Javascript
StringTemplate遇见jQuery冲突的解决方法
2011/09/22 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
2013/02/05 Javascript
javascript时间差插件分享
2016/07/18 Javascript
微信小程序数据存储与取值详解
2018/01/30 Javascript
详解Vue中的基本语法和常用指令
2019/07/23 Javascript
vue实现二级导航栏效果
2019/10/19 Javascript
js实现登录时记住密码的方法分析
2020/04/05 Javascript
Python语言描述最大连续子序列和
2017/12/05 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
python中比较两个列表的实例方法
2019/07/04 Python
python不同系统中打开方法
2020/06/23 Python
python爬取音频下载的示例代码
2020/10/19 Python
Python使用tkinter实现小时钟效果
2021/02/22 Python
python包的导入方式总结
2021/03/02 Python
MIKI HOUSE美国官方网上商店:日本领先的婴儿和儿童高级时装品牌
2020/06/21 全球购物
TCP/IP模型的分界线
2012/12/01 面试题
英语简历自我评价
2014/01/26 职场文书
家居装修公司创业计划书范文
2014/03/20 职场文书
优秀电子工程系毕业生求职信
2014/05/24 职场文书
大学生党员自我剖析材料
2014/10/06 职场文书
2015年乡镇环保工作总结
2015/04/22 职场文书
致短跑运动员加油稿
2015/07/21 职场文书
工商局调档介绍信
2015/10/22 职场文书
小学生纪律委员竞选稿
2015/11/19 职场文书
Python 中 Shutil 模块详情
2021/11/11 Python