PHP下使用强大的imagick轻松生成组合缩略图
project: blog
target: use-imagick-to-composite-images-thumbnail.md
date: 2016-02-19
status: publish
tags:
    - php
    - imagick
    - thumbnail
categories:
    - php
这里说的imagick 是 ImageMagick 在PHP下的扩展。使用pecl安装起来那叫一个轻松简单 —— 一条命令就搞定:
sudo pecl install imagick
(扩展装好后还是要在php.ini中加上extension=imagick.so,然后记得重启apache或php-fpm服务。)
最近有个需求是要把多张图片组合起来生成缩略图,刚好用用这个强大的imagick扩展。
这个需求是要这样生成缩略图:
- 如果有1张图片,就直接生成这张图片的缩略图;
 - 如果有2张图片,则一张在左边一张在右边,各一半;
 - 如果有3张图片,则两张左边平均分配,一张独占右边;
 - 如果有4张图片,则像田字格一样平均分配空间;
 - 更多张图片,则只取前4张,按田字格方式生成缩略图。
 
这规则还真不少,不过还不算太过复杂,很快搞出来了:
namespace \clarence\thumbnail;
class Thumbnail extends \Imagick
{
    /**
     * @param array $images
     * @param int $width
     * @param int $height
     * @return static
     * @throws ThumbnailException
     */
    public static function createFromImages($images, $width, $height){
        if (empty($images)){
            throw new ThumbnailException("No images!");
        }
        $thumbnail = new static();
        $thumbnail->newImage($width, $height, 'white', 'jpg');
        $thumbnail->compositeImages($images);
        return $thumbnail;
    }
    public function compositeImages($images){
        $imagesKeys = array_keys($images);
        $compositeConfig = $this->calcCompositeImagesPosAndSize($images);
        foreach ($compositeConfig as $index => $cfg){
            $imgKey = $imagesKeys[$index];
            $img = new \Imagick($images[$imgKey]);
            $img = $this->makeCompositeThumbnail($img, $cfg);
            $this->compositeImage($img, self::COMPOSITE_OVER, $cfg['to']['x'], $cfg['to']['y']);
        }
    }
    protected function makeCompositeThumbnail(\Imagick $img, $cfg){
        $img->cropThumbnailImage($cfg['size']['width'], $cfg['size']['height']);
        return $img;
    }
    protected function calcCompositeImagesPosAndSize($images){
        $width = $this->getImageWidth();
        $height = $this->getImageHeight();
        switch(count($images)){
            case 0:
                throw new ThumbnailException("No images!");
            case 1:
                // | 0 |
                return [
                    0 => [
                        'to' => [ 'x' => 0, 'y' => 0 ],
                        'size' => [
                            'width' => $width,
                            'height' => $height,
                        ]
                    ]
                ];
            case 2:
                // | 0 | 1 |
                return [
                    0 => [
                        'to' => [ 'x' => 0, 'y' => 0 ],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height,
                        ]
                    ],
                    1 => [
                        'to' => [ 'x' => $width / 2, 'y' => 0],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height,
                        ]
                    ]
                ];
            case 3:
                // | 0 | 1 |
                // | 2 |   |
                return [
                    0 => [
                        'to' => [ 'x' => 0, 'y' => 0 ],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height / 2,
                        ]
                    ],
                    1 => [
                        'to' => [ 'x' => $width / 2, 'y' => 0],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height,
                        ]
                    ],
                    2 => [
                        'to' => [ 'x' => 0, 'y' => $height / 2 ],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height / 2,
                        ]
                    ],
                ];
            default:
                // >= 4:
                // | 0 | 1 |
                // | 2 | 3 |
                return [
                    0 => [
                        'to' => [ 'x' => 0, 'y' => 0 ],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height / 2,
                        ]
                    ],
                    1 => [
                        'to' => [ 'x' => $width / 2, 'y' => 0],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height / 2,
                        ]
                    ],
                    2 => [
                        'to' => [ 'x' => 0, 'y' => $height / 2 ],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height / 2,
                        ]
                    ],
                    3 => [
                        'to' => [ 'x' => $width / 2, 'y' => $height / 2],
                        'size' => [
                            'width' => $width / 2,
                            'height' => $height / 2,
                        ]
                    ],
                ];
        }
    }
}
用个试试:
$thumbnail = \clarence\thumbnail\Thumbnail::createFromImages($srcImages, 240, 320);
$thumbnail->writeImage($outputDir."/example.jpg");
效果立马出来了:

赞一个~
(详细代码见 http://github.com/clarence-pan/thumbnail)
PHP下使用强大的imagick轻松生成组合缩略图的更多相关文章
- windows7下安装php的imagick和imagemagick扩展教程
		
这篇文章主要介绍了windows7下安装php的imagick和imagemagick扩展教程,同样也适应XP操作系统,Win8下就没测试过了,需要的朋友可以参考下 最近的PHP项目中,需要用到切图和 ...
 - linux下安装php的imagick扩展模块(附php升级脚本)
		
imagick是一个PHP的扩展,是一套软件系列,用ImageMagick提供的API来进行图片的创建与修改,不过这些操作已经包装到扩展imagick中去了,最终调用的是ImageMagick提供的A ...
 - 善用GIMP(Linux下的Photoshop),图像处理轻松又自由
		
善用GIMP(Linux下的Photoshop),图像处理轻松又自由 作者: 善用佳软 日期: 2013-02-16 分类: 2 图像影音 标签: GIMP, image 1. GIMP是什么? GI ...
 - gen目录无法更新,或者gen目录下的R.JAVA文件无法生成
		
gen目录无法更新,或者gen目录下的R.JAVA文件无法生成 1.gen目录的用处 android gen目录下的R.java并不是由用户创建,而是android工程本身将android的资源进行自 ...
 - PHP一般情况下生成的缩略图都比较不理想
		
PHP用GD库生成高质量的缩略图片,PHP一般情况下生成的缩略图都比较不理想.今天试用PHP,GD库来生成缩略图.虽然并不100%完美.可是也应该可以满足缩略图的要求了.<?php $FILEN ...
 - 9.1.2 asp.net core 自动生成组合查询
		
在做系统的时候,经常遇到前台录入一大堆的查询条件,然后点击查询提交后台,在Controller里面生成对应的查询SQL或者表达式,数据库执行再将结果返回客户端. 例如如下页面,输入三个条件,日志类型. ...
 - ASP.NET根据URL生成网页缩略图示例程序(C#语言)
		
工作中可能马上要用到根据URL生成网页缩略图功能,提前做好准备. 在网上找了份源码,但是有错误:当前线程不在单线程单元中,因此无法实例化 ActiveX 控件“8856f961-340a-11d0-a ...
 - 利用FFmpeg生成视频缩略图 2.3.1
		
1.下载FFmpeg文件包,解压包里的\bin\下的文件解压到 D:\ffmpeg\ 目录下. 下载地址 http://ffmpeg.zeranoe.com/builds/win32/static/ ...
 - 利用FFmpeg生成视频缩略图 2.1.8
		
1.下载FFmpeg文件包,解压包里的\bin\下的文件解压到 D:\ffmpeg\ 目录下. 下载地址 http://ffmpeg.zeranoe.com/builds/win32/static/ ...
 
随机推荐
- 自动生成build.xml文件
			
使用Eclipse 自动生成 Ant的Build.xml 配置文件,选择要生成Build.xml文件的项目,鼠标右键, Export-> General -> Ant Buildfiles ...
 - 无线OSS-高精度整数加法
			
#include<iostream> #include<string> using namespace std; int compareStr(string str1, str ...
 - stopping NetworkManager daemon failed
			
1 初次安装NetworkManager时发现,无法将这个服务关闭 2 上网找了一圈,也没找到原因 3 重启服务器后就能正常关闭了 4 将该服务删除重装也能正常关闭 5 下回重装系统时再观察一下
 - 【原创】MVC4+Jquery+EasyUI实现的工作流平台
			
最近把工作流从传统的WebFrom上迁移到我的MVC4安全权限基础框架中,感觉非常不错MVC4在各方面给用户的体验确实跟以前传统的WEB是质的提升.由于后面要做基于工作流技术的ERP,所以需要先把工作 ...
 - [转]http-关于application/x-www-form-urlencoded等字符编码的解释说明
			
在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型. 下边是说明: application/x-www-form-urlen ...
 - [css]水平垂直居中的方法
			
1.top:cale(50% - 2rem); left:cale(50% - 2rem);
 - thunkify 模块
			
function thunkify(fn){ assert('function' == typeof fn, 'function required'); return function(){ var ...
 - ScrollView can host only one direct child
			
Android 采用ScrollView布局时出现异常:ScrollView can host only one direct child. 异常原因: 主要是ScrollView内部只能有一个子元素 ...
 - 查找“asdfjvjadsffvaadfkfasaffdsasdffadsafafsafdadsfaafd” 该字符串中有多少个af
			
package lovo.bean; import java.util.Scanner; public class Java { @param args public static void main ...
 - 百度echarts地图扩展动态加载geoCoord
			
var data={}; for(var i=0;i<result.length;i++){ data[(""+result[i].name+"")]=e ...