php用Imagick模块完美实现GIF动画缩略图代码实例

时间:2018-05-04 作者:佚名 编辑:xiaoxin 来源:不甘平庸网

缩略图是个很常用的功能。它的实现并不复杂,但如果原图是GIF动画的话,问题就会变得繁琐一点。

下面通过一个取自CS警匪游戏的GIF动画来说明问题:

php用Imagick模块完美实现GIF动画缩略图代码实例

GIF动画图片:old.gif

为了让问题更加清晰,我们先还原动画各帧:

选择一:用PHP中的Imagick模块:


代码如下: 
<?php 
$image = new Imagick('old.gif'); 
$i = 0; 
foreach ($image as $frame) { 
$frame->writeImage('old_' . $i++ . '.gif'); 
} 
?> 

php用Imagick模块完美实现GIF动画缩略图代码实例

选择二:用ImageMagick提供的convert命令:

代码如下:

shell> convert old.gif old_%d.gif

结果得到GIF动画各帧示意图如下所示:

php用Imagick模块完美实现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

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

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

相关阅读
  • PHP怎样判断一个gif图片是否为动态图片(动画)?
    如何使用PHP来判断一个gif图片是否为动态图片(动画)?首先想到的是使用getimagesize()函数来看type值,发现都是gif,所以这个办法是不可行的。下面是作者在网上看到的一个函数,经测试,可以用来判断gif是否为动图。... [详情]
  • Linux和windows7下安装php的imagick和imagemagick扩展教程
    最近的PHP项目中,需要用到切图和缩图的效果,在Linux测试服务器上很轻松的就安装好php imagick扩展。但是在本地windows开发环境,安装过程遇到好多问题,在此与大家分享。... [详情]
  • php服务器500错误无输出,快速定位错误代码万能调试方法
    网站线下调试没有问题,放到线上报500错误,无输出,无报错,日志正常,如何才能快速定位错误代码?经过网上搜索,找到一种方法:万能调试代码法,问题得到解决。... [详情]
  • php使用fsockopen读取分段数据出现多余字符的解决方法
    使用fsockopen读取数据时遇到了一个神奇的问题,具体情况如下:请注意上面那些标红的4个字符,它们每隔一段数据就会出现一次,但是用其他的方法如curl,file_get_contents等取回的数据则没有这些玩意。换成其他的网站... [详情]
  • php去掉fsockopen返回结果中的HTTP头信息的方法
    去掉fsockopen返回结果中的HTTP头信息的两种方法:1、【使用split或substr,strpos截断】在返回的内容中HTTP头信息与正文内容是以两个“换行回车”隔开的所以我们可以在此截断,取之后的内容。2、【先取Content-Length... [详情]
  • PHP环境下Memcache的使用方法详解
    Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在... [详情]
  • php在用file_get_contents抓取网页时出现乱码的2种解决方式
    今天自己在写一个程序,抓取别人的网页,之前公司有些功能也会需要,但是今天在抓取网页的时候发现了一个问题用file_get_contents抓取网页发现乱码情况。于是用转换编码$contents = iconv("gb2312", "utf-8//IGNORE... [详情]
  • php iconv函数在gb232与utf-8之间转码时出错断掉的解决方法
    最近在做一个采集程序,需要用到iconv函数把抓取来过的gb2312编码的页面转成utf-8, 发现只有用iconv函数把抓取过来的数据一转码数据就会无缘无故的少一部分。让我郁闷了好一会儿,去网上一查资料才知道这是iconv函... [详情]
  • php操作excel的类:PHPExcel 1.8.0使用方法
    首先到phpexcel官网上下载最新的phpexcel类,下载解压缩一个classes文件夹,里面包含了PHPExcel.php和PHPExcel的文件夹,这个类文件和文件夹是我们需要的,把classes解压到你项目的一个目录中,重名名为phpexcel,代... [详情]
  • PHP字符串定义的几种方式
    如果遇到需要多行书写的字符串怎么办,比如我们要定义一段JS脚本,当然如果把脚本写在一行里是没问题的,但是如果脚本比较长一些,而且其中会出现很多转义符号的话,脚本最终成型的话,很有可能成了一锅黏粥了。不但... [详情]
  • PHP匿名函数详解
    PHP匿名函数 匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)的参数。 当然,也有其他应用的情况。... [详情]
  • php cli模式传递和获取参数的方法
    php cli模式传递和获取参数的方法
    在命令行里输入程序参数来更改其运行方式是很常见的做法。你也可以对CLI程序这样做。PHP CLI带有两个特殊的变量,专门用来达到这个。目的:一个是$argv变量,它通过命令行... [详情]
  • php通过QRCode类库创建中间带网站LOGO的二维码实例
    我们要生成二维码都需要借助一些类库来实现了,下面我介绍利用PHP QR Code生成二维码吧,生成方法很简单,下面我来介绍一下.利用php类库PHP QR Code来实现,不需要装额外的php扩展,首先下载类库包,有时候地址打不开,地址... [详情]
  • php详解session_id()应在session_start()前还是后?
    大家通过手册可以知道session的恢复通过session_id($id);但是在恢复时要注意一个先后顺序,要得到之前session的内容,必须在session_start()之前执行session_id($id),这样才能在执行了session_start时初始化session... [详情]
  • PHP 之父:PHP7 性能翻倍关键大揭露
    PHP 之父:PHP7 性能翻倍关键大揭露
    20岁老牌网页程序语言PHP,将在10月底释出PHP 7新版,这是十年来的首次大改版,最大特色是在性能上的大突破,能比前一版PHP 5快上一倍,PHP之父Rasmus Lerdorf表示,甚至能... [详情]
  • php正则表达式:正向预查:(?=)、 反向预查:(?<=) 捕获数据
    php正则表达式:正向预查:(?=) 相对应的 (?!)表示否定意思。反向预查:(?<=) 相对应的 (?<!)表示否定意思。避免捕获数据:格式:(?:pattern) 优点:将使有效反向引用数量保持在最小,代码更加、清楚。限定符?如果前面... [详情]
  • php 详解如何阻止网站被恶意反向代理访问(即防网站镜像)
    网站被恶意反向代理有什么危害呢?首先肯定会占用服务器资源,网站打开速度受影响。其次,别人通过代理盗用你的网站数据,对用户与不是那么智能的搜索引擎而言,相当于建了一个与你一模一样的站点,那么很有可能你的... [详情]
  • php 详解$_SERVER中的SERVER_NAME 和HTTP_HOST的区别
    不同点:1、$_SERVER["HTTP_HOST"] 在HTTP/1.1协议规范下,会根据客户端的HTTP请求输出信息。_SERVER["SERVER_NAME"] 默认情况下直接输出apache的配置文件httpd.conf中的ServerName值。2、当服务器为非80端口时:$_S... [详情]
  • php读取目录及子目录下所有文件名的方法实例
    在程序脚本开发中,有时不可避免要操作文件。php读取目录及子目录下所有文件名的方法更是少不了,现分享代码给大家供参考。 [详情]
  • php curl库函数用法
    使用PHP的cURL库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据... [详情]
PHP心得推荐
频道推荐
本周推荐
点击排行