完美实现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安全技术之 实现php基本安全
Sep 04 PHP
php学习笔记之 函数声明
Jun 09 PHP
查找mysql字段中固定字符串并替换的几个方法
Sep 23 PHP
ThinkPHP框架搭建及常见问题(XAMPP安装失败、Apache/MySQL启动失败)
Apr 15 PHP
Thinkphp3.2.3分页使用实例解析
Jul 28 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
Nov 10 PHP
学习thinkphp5.0验证类使用方法
Nov 16 PHP
php实现生成带二维码图片并强制下载功能
Feb 24 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
May 12 PHP
php7下的filesize函数
Sep 30 PHP
基于PHP实现生成随机水印图片
Dec 09 PHP
PHP7 其他语言层面的修改
Mar 09 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+SqlServer实现分页显示
2006/10/09 PHP
PHP中根据IP地址判断城市实现城市切换或跳转代码
2012/09/04 PHP
php使用curl和正则表达式抓取网页数据示例
2014/04/13 PHP
在Nginx上部署ThinkPHP项目教程
2015/02/02 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
PHP简单实现正则匹配省市区的方法
2018/04/13 PHP
YII分模块加载路由的实现方法
2018/10/01 PHP
超级退弹代码
2008/07/07 Javascript
超越Jquery_01_isPlainObject分析与重构
2010/10/20 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
2013/10/29 Javascript
js键盘上下左右键怎么触发function(实例讲解)
2013/12/14 Javascript
jquery删除提示框弹出是否删除对话框
2014/01/07 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
2014/03/05 Javascript
三种检测iPhone/iPad设备方向的方法
2014/04/23 Javascript
jQuery使用addClass()方法给元素添加多个class样式
2015/03/26 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
JavaScript实现添加、查找、删除元素
2015/07/02 Javascript
再次谈论Javascript中的this
2016/06/23 Javascript
Vuejs第十二篇之动态组件全面解析
2016/09/09 Javascript
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
微信小程序实现文字跑马灯效果
2020/05/26 Javascript
Vue中插入HTML代码的方法
2018/09/21 Javascript
ES6小技巧之代替lodash
2019/06/07 Javascript
JavaScript JSON数据处理全集(小结)
2019/08/15 Javascript
js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结
2020/03/04 Javascript
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
浅谈Python中的作用域规则和闭包
2018/03/20 Python
Python3实现转换Image图片格式
2018/06/21 Python
用python标准库difflib比较两份文件的异同详解
2018/11/16 Python
浅析python内置模块collections
2019/11/15 Python
python 解决Fatal error in launcher:错误问题
2020/05/21 Python
施华洛世奇加拿大官网:SWAROVSKI加拿大
2018/06/03 全球购物
九年级物理教学反思
2014/01/29 职场文书
情侣吵架检讨书
2014/02/05 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
2015年人事科工作总结
2015/04/28 职场文书