完美实现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 相关文章推荐
php4的彩蛋
Oct 09 PHP
mysql+php分页类(已测)
Mar 31 PHP
php 前一天或后一天的日期
Jun 28 PHP
超级好用的一个php上传图片类(随机名,缩略图,加水印)
Jun 30 PHP
PHP flush()与ob_flush()的区别详解
Jun 03 PHP
php数组(array)输出的三种形式详解
Jun 05 PHP
php使用explode()函数将字符串拆分成数组的方法
Feb 17 PHP
PHP中基本HTTP认证技巧分析
Mar 16 PHP
php array_merge函数使用需要注意的一个问题
Mar 30 PHP
php中使用gd库实现远程图片下载实例
May 12 PHP
php生成固定长度纯数字编码的方法
Jul 09 PHP
PHP调用其他文件中的类
Apr 02 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/11/22 PHP
php+mysql写的简单留言本实例代码
2008/07/25 PHP
PHP投票系统防刷票判断流程分析
2012/02/04 PHP
PHPExcel内存泄漏问题解决方法
2015/01/23 PHP
php自定义类fsocket模拟post或get请求的方法
2015/07/31 PHP
[原创]php正则删除img标签的方法示例
2017/05/27 PHP
JavaScipt中的Math.ceil() 、Math.floor() 、Math.round() 三个函数的理解
2010/04/29 Javascript
详解Document.Cookie
2015/12/25 Javascript
JS中的二叉树遍历详解
2016/03/18 Javascript
jQuery多个版本和其他js库冲突的解决方法
2016/08/11 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
Angular如何引入第三方库的方法详解
2017/07/13 Javascript
AngularJS 中ui-view传参的实例详解
2017/08/25 Javascript
js提取中文拼音首字母的封装工具类
2018/03/12 Javascript
vue中element 上传功能的实现思路
2018/07/06 Javascript
浅析java线程中断的办法
2018/07/29 Javascript
JQuery常用简单动画操作方法回顾与总结
2019/12/07 jQuery
es6中new.target的作用和使用场景简单示例分析
2020/03/14 Javascript
Python isinstance函数介绍
2015/04/14 Python
python验证码识别教程之利用投影法、连通域法分割图片
2018/06/04 Python
Django ORM 聚合查询和分组查询实现详解
2019/08/09 Python
python网络爬虫 CrawlSpider使用详解
2019/09/27 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
New Balance法国官方网站:购买鞋子和服装
2019/09/01 全球购物
护理工作感言
2014/01/16 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
志愿者活动总结
2014/04/28 职场文书
小学毕业典礼演讲稿
2014/09/09 职场文书
大学新生军训自我鉴定
2014/09/18 职场文书
公司授权委托书
2014/10/17 职场文书
分居协议书范本
2014/11/03 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
python实现简单反弹球游戏
2021/04/12 Python
CSS+HTML 实现顶部导航栏功能
2021/08/30 HTML / CSS
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js