完美实现GIF动画缩略图的php代码

 更新时间:2011年01月02日 00:08:14   作者:  
缩略图是个很常用的功能。它的实现并不复杂,但如果原图是GIF动画的话,问题就会变得繁琐一点。
下面通过一个取自CS警匪游戏的GIF动画来说明问题:
GIF动画图片:old.gif

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动画各帧示意图

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如下:

 

new.gif

new.gif

有个细节问题:convert版本会比php版本小一些,这是API实现不一致所致。

另外,如果缩略图尺寸不符合原图比例,为了避免变形,还要考虑裁剪或者是补白,由于本文主要讨论GIF动画缩略图的特殊性,就不再继续讨论这些问题了,有兴趣的自己搞定吧。

相关文章

  • php下获取http状态的实现代码

    php下获取http状态的实现代码

    在项目开发中,有时我们需要知道远程的URL地址是否能访问正常,判断其正常与否后进行下一步的操作,那么在PHP中如何获取远程HTTP的状态呢
    2014-05-05
  • Yii PHP Framework实用入门教程(详细介绍)

    Yii PHP Framework实用入门教程(详细介绍)

    本篇文章是对Yii PHP Framework实用入门教程进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • linux平台编译安装PHP7并安装Redis扩展与Swoole扩展实例教程

    linux平台编译安装PHP7并安装Redis扩展与Swoole扩展实例教程

    这篇文章主要介绍了linux平台编译安装PHP7并安装Redis扩展与Swoole扩展的方法,结合实例形式详细分析了Linux平台上安装php7并安装Redis扩展与Swoole扩展的具体步骤与操作技巧,需要的朋友可以参考下
    2016-09-09
  • PHP弱类型的安全问题详细总结

    PHP弱类型的安全问题详细总结

    弱类型语言也称为弱类型定义语言。与强类型定义相反。像vb,php等就属于弱类型语言,这篇文章给大家详细介绍关于PHP弱类型的安全问题,有需要的可以参考借鉴,下面来一起看看吧。
    2016-09-09
  • php中邮箱地址正则表达式实现与详解

    php中邮箱地址正则表达式实现与详解

    本文章不但要讲述了关于正则达式而且还讲述了关于邮箱正则的构成用法详解,有需要了解的朋友可以参考一下,同时我们也提供了多种不同的邮箱验证实例
    2012-04-04
  • php实现excel中rank函数功能的方法

    php实现excel中rank函数功能的方法

    这篇文章主要介绍了php实现excel中rank函数功能的方法,较为详细的分析了rank函数的功能及具体实现方法,需要的朋友可以参考下
    2015-01-01
  • php实现session自定义会话处理器的方法

    php实现session自定义会话处理器的方法

    这篇文章主要介绍了php实现session自定义会话处理器的方法,可通过设置session.save_handler为user来调用自定义的回调函数,从而实现session自定义会话处理器的功能,非常具有实用价值,需要的朋友可以参考下
    2015-01-01
  • PHP实现异步定时多任务消息推送

    PHP实现异步定时多任务消息推送

    在 PHP 中实现异步定时多任务消息推送的方式有多种,其中一种常用的方式是使用异步任务队列,这篇文章主要介绍了这一方法的具体实现,需要的可以参考一下
    2023-04-04
  • php IP及IP段进行访问限制的代码

    php IP及IP段进行访问限制的代码

    本来是写了几个函数,IP黑名单是记到库里的,为了方便理解,改成了一个class把IP黑名单写了出来。
    2008-12-12
  • php利用jsonp实现跨域

    php利用jsonp实现跨域

    JSONP(JSON with Padding)是一种使用普通的<script>标签来发起跨域请求的方法,本文主要为大家详细介绍了PHP如何利用jsonp实现跨域,需要的可以参考下
    2023-11-11

最新评论