完美实现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 相关文章推荐
example2.php
Oct 09 PHP
PHP的中问验证码
Nov 25 PHP
PHP与SQL注入攻击[一]
Apr 17 PHP
实用函数4
Nov 08 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
Oct 08 PHP
php实现编辑和保存文件的方法
Jul 20 PHP
作为程序员必知的16个最佳PHP库
Dec 09 PHP
Symfony2安装的方法(2种方法)
Feb 04 PHP
PHP+JS三级菜单联动菜单实现方法
Feb 24 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
Oct 22 PHP
laravel框架邮箱认证实现方法详解
Nov 22 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
Feb 27 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链表用法实例分析
2015/07/09 PHP
PHP制作用户注册系统
2015/10/23 PHP
Smarty模板引擎缓存机制详解
2016/05/23 PHP
PHP中isset、empty的用法与区别示例详解
2020/11/05 PHP
jQuery的实现原理的模拟代码 -4 重要的扩展函数 extend
2010/08/03 Javascript
javascript常用对话框小集
2013/09/13 Javascript
js每隔5分钟执行一次ajax请求的实现方法
2013/11/27 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
2014/02/11 Javascript
JS定义网页表单提交(submit)的方法
2015/03/20 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
2015/06/05 Javascript
javascript实现动态统计图开发实例
2015/11/21 Javascript
jquery限定文本框只能输入数字(整数和小数)
2016/01/08 Javascript
标准的js无缝滚动效果
2016/08/30 Javascript
解决URL地址中的中文乱码问题的办法
2017/02/10 Javascript
Vue.js路由vue-router使用方法详解
2017/03/20 Javascript
全面解析vue router 基本使用(动态路由,嵌套路由)
2018/09/02 Javascript
Vue实现底部侧边工具栏的实例代码
2018/09/03 Javascript
JS开发自己的类库实例分析
2019/08/28 Javascript
微信域名检测接口调用演示步骤(含PHP、Python)
2019/12/08 Javascript
JS实现音乐钢琴特效
2020/01/06 Javascript
vue中用 async/await 来处理异步操作
2020/07/18 Javascript
js实现简单的无缝轮播效果
2020/09/05 Javascript
JavaScript大数相加相乘的实现方法实例
2020/10/18 Javascript
Python中使用MELIAE分析程序内存占用实例
2015/02/18 Python
python中zip和unzip数据的方法
2015/05/27 Python
Python修改MP3文件的方法
2015/06/15 Python
python logging 日志轮转文件不删除问题的解决方法
2016/08/02 Python
浅析Python中元祖、列表和字典的区别
2016/08/17 Python
Python实现语音识别和语音合成功能
2019/09/20 Python
redis数据库及与python交互用法简单示例
2019/11/01 Python
在python中logger setlevel没有生效的解决
2020/02/21 Python
python爬虫容易学吗
2020/06/02 Python
python 制作python包,封装成可用模块教程
2020/07/13 Python
青年教师培训方案
2014/02/06 职场文书
学校搬迁方案
2014/06/15 职场文书
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server