很多PHPER在处理图片库的时候都会选择Imagine,不过这个库只有英文文档,昨日翻译一下,送给需要的同学。

Imagine是一个PHP5.3+的图片处理库,对于图片的处理可以使用GD2、Imagick或Gmagick。

能实现什么

Imagine具有强大的功能和简洁的API接口,众多PHP框架都采用Imagine来完成对图片的操作。

目前为止Imagine能实现功能如下

  • 图片的大小调整及裁剪等操作。
  • 绘图,创建基本图形和高级图表。
  • 蒙版功能,实现图像的半透明或绝对透明功能。

安装Imagine

可以使用composer方便的进行Imagine安装,如下代码

php composer.phar require imagine/imagine
复制代码

在这一章我们使用Imagine完成一些有趣的事情,通过这些事情你可以熟悉Imagine的使用流程。

目录结构

我们先来熟悉一下Imagine库的目录结构

上面目录具体干的事情如下

  • Draw
  • Effects
  • Exception
  • Filter
  • Gd
  • Gmagick
  • Image
  • Imagick
  • resources

不要被这么多目录所迷惑,Imagine是一个设计非常清晰及现代的图片库,支持了主流的底层库,扩展性非常强,作者为了后期扩展方便提供了几个基础接口来撑起Imagine。

它们分别是

  • ImagineInterface
  • ImageInterface
  • FontInterface
  • DrawerInterface
  • ....

这里面最重要的是 ImagineInterfaceImageInterface

ImagineInterface

ImagineInterface是Imagine的核心,一起从它开始,它存在于 Imagine/Image/ImagineInterface.php ,当然这是一个接口,针对Gd、Imagick和Gmagick不同的库,在对应文件夹的 Imagine.php 文件对此接口进行了实现,具体位置请看下面列表。

  • Imagine/Gd/Imagine.php
  • Imagine/Gmagick/Imagine.php
  • Imagine/Imagick/Imagine.php

ImagineInterface就像一个工厂,通过ImagineInterface接口的类可以新建、打开图像,并且返回一个 ImageInterface 对象,而在 ImageInterface 提供了对图片的具体操作。

现在我们来举一个例子

$imagine = new ImagineGdImagine();
$image = $imagine->open('/xxx/image.jpg');
复制代码

上面的例子逻辑是这样的

  • 首先建立一个ImagineInterface对象$imagine,这里使用的是GD库
  • 使用 image

ImageInterface

通过上面的ImagineInterface我们打开了一个对象,并且得到了ImageInterface的实例化对象,ImageInterface也是一个抽象的接口,针对不同的库有不同的实现,它们都在叫做Image的类中,目录如下

  • Imagine/Gd/Image.php
  • Imagine/Gmagick/Image.php
  • Imagine/Imagick/Image.php

打开任何一个Image.php,你会发现很多熟悉的单词,比如copy、resize、save、fill等很多方法,这些就是对图片的具体操作,当然在这里还可以通过于FontInterface、DrawerInterface等实现更加牛x的效果。

接下来我们扩展下上面的例子

$imagine = new ImagineGdImagine();
$image = $imagine->open('/xxx/image.jpg');
$image->save('/xxx/image.png');
复制代码

上面的例子是在xxx目录下对于打开的图片image.jpg,另存为image.png格式,很方便。

总结

我们来总结一下,Imagine的核心思路非常简单,提供足够清晰的接口并且容纳足够多的图片处理库,针对于对图片的不同操作,比如Draw、Effects、Filter等建立一系列的接口,然后在具体的库中对这些接口进行实现。

所以我们在Gd、Gmagick和Imagick文件下内你看到了相同名称的文件。

  • Drawer.php
  • Effects.php
  • Font.php
  • Image.php
  • Imagine.php
  • Layers.php

一套接口,各种库对其进行实现,这就是Imagine


首先我们要学习下什么是元数据? 元数据是用来描述数据的数据(Data that describes other data),比如一张数码照片我们可以读取到拍此照片的相机类型、品牌等等,这些就是元数据。

大神阮一峰曾写了一篇小文来说元数据,感兴趣的可以看看。传送门

访问图像元数据

有了Imagine,读取元数据变的非常简单,我们只需要调用方法即可,请看例子。

$imagine = new ImagineGdImagine();
$image = $imagine->open('/xxx/image.jpg');
var_dump($image->metadata());
复制代码

我们使用metadata方法得到基本的元数据,看看输出数据的解构。

通过结果我们看到metadata方法得到的是 ImageMetadataMetadataBag 类对象,包含的信息是 filepath 和 uri。

元数据读取器(metadata reader)

你可能差异元数据就这点信息么?还可以更多

Imagine内置提供了两种元数据读取器,它们负责读出图像元数据并提供给上面的metadata,默认的读取器是 Imagine/Image/Metadata/DefaultMetadataReader.php

还有一个叫做 Imagine/Image/Metadata/ExifMetadataReader.php,使用 ExifMetadataReader可以读取图像的Exif信息,接下来我们学习如何让Imgaine使用 ExifMetadataReader 读取器。

use ImagineImageMetadataExifMetadataReader;$imagine = new ImagineGdImagine();
$image = $imagine->setMetadataReader(new ExifMetadataReader())->open('/xxx/image.jpg');
var_dump($image->metadata());
复制代码

看明白了吧,我们需要调用 $imagine 的setMetadataReader方法并传入ExifMetadataReader对象。

注意 ExifMetadataReader的生效需要你的PHP拥有exif扩展,否则会有如下报错。

当这一切都满足后,你通过 metadata() 得到的 MetadataBag 对象将拥有Exif信息,你可以获得更多有用的。

自定义

一般来说使用 ExifMetadataReader 我们就足以满足业务需求了,但是Imagine还是提供了MetadataReaderInterface接口,允许我们自己定义自己的元数据读取器。

方法可以参考内置的另种读取器,继承于虚拟类 AbstractMetadataReader即可。


在Imagine处理图片时坐标是一个非常重要的概念,比如裁剪、伸缩等等都需要用到它,本章带你了解它。

坐标系统

在初中的时候我们学过坐标系,它叫笛卡尔坐标,如下图

这是我们学的,左下角是起点(x=0,y=0),但是Imagine坐标系统中起点位置有所不同,它以左上角为起点,相应地向右和向下延伸。另外就是没有负坐标。

相关类

Imagine中提供给了两个接口,分别是

  • ImagineImagePointInterface 表示边界框中的单个点
  • ImagineImageBoxInterface 代表尺寸(宽度,高度)

分别比ImagineImage下的Box类和Point类所实现,并且被其他类所使用,比如当我们调用$image->getSize的时候就用到。

PointInterface

每一个坐标都有如下方法

  • getX()
  • getY()
  • in(BoxInterface $box)
  • __toString()

BoxInterface

每个盒子或图像或形状都有一个大小,以下几种方法:

  • getWidth() - 返回整数宽度
  • getHeight() - 返回整数高度
  • scale(ratio
  • increase(size添加给每一方
  • contains(BoxInterface start = null)-检查给定start位置。如果没有$start给出位置,则假定为(0,0)
  • square()- 返回整数的当前平方,例如BoxInterface,用于确定框中像素的总数
  • __toString()- 返回当前的字符串表示BoxInterface,例如100x100 px
  • widen($width) - 将框调整为给定宽度,约束比例并返回新框
  • heighten($height) - 将框调整到给定高度,约束比例并返回新框

场景

PointInterface 和 BoxInterface 经常用到其他方法或新建一个图像并绘制的场景,关于这些场景我们会在接下来的章节中逐渐涉及。


Imagine提供了比较强大的绘制能力,我们可以通过Imagine新建一个模板,然后绘制图形。在这一篇里你也能更加熟练的使用上一篇的坐标相关接口。

做一个图

我们现在实现一个需求,很简单,一张橙色背景400x300的图像,然后画一个线,开始啦

use ImagineGdImagine;
use ImagineImagePoint;
use ImagineImageBox;
use ImagineImagePaletteRGB;$palette = new RGB();
$imagine = new Imagine();
$box = new Box(400,300);
$image = $imagine->create($box,$palette->color('#FF6900'));
$image->draw()->line(new Point(200,150),new Point(250,250),$palette->color('#000000'));$image->show('png');
复制代码

上面代码的结果如下

结果分析

针对上面的图片,我们来复盘一下Imagine的实现思路。

  • 首先我们要使用 $imagine->create 方法生成一个图像,图像包含尺寸和背景色。
  • 尺寸是由上一篇的Box接口实现类来完成的,$box = new Box(400,300);,颜色则是RGB类。
  • 然后调用$image的draw()方法,此方法的结果是得到一个drawer对象,同时拥有很多方法。
  • 我们使用drawer对象的line方法,画一条线。
  • 随后将图片以png的格式展示出来。

绘制方法一览

通过上面我们知道要绘图其实是调用了Image对象的draw方法,此刻我们看看draw内部的逻辑。

// Imagine/Gd/Image.php
public function draw()
{return new Drawer($this->resource);
}
复制代码

draw方法如此简单,仅仅return了Drawer的实例化对象,因此Imagine的绘图功能就回到了Drawer类上了。

还记得我们之前说的么?Imagine更多是提供了一系列的接口,因此在Gd等库中的Drawer类就是对DrawerInterface接口的实现,这个接口在 Imagine/Draw/DrawerInterface.php 中。

接下来我们看看Imagine的绘图功能到底有哪些?

  • arc 弧线
  • chord 弦
  • ellipse 椭圆
  • line 直线
  • pieSlice 饼图
  • dot 点
  • polygon 多边形
  • text 文字

对,DrawerInterface接口定义了8个方法,所以实现此接口的类都需要实现它们,绘图是最好练习Box和Point的途径,建议你多画一画。


一般来说,当我们使用Imagine时涉及到了颜色,不会直接传递颜色值,而是传递一个Palette对象,比如下面的例子。

$palette = new ImagineImagePaletteCMYK();
$imagine->create(new ImagineImageBox(10, 10), $palette->color('#FFFFFF'));
复制代码

支持类

Imagine提供了两个类,RGB和CMYK。

  • new ImagineImagePaletteRGB();
  • new ImagineImagePaletteCMYK();

使用上首先调用响应的类,实例化

$palette = new ImagineImagePaletteRGB();
复制代码

得到对象后调用color方法,传入颜色值,得到一个Color对象,这个Color对象经常作为其他方法的参数。

$white = $palette->color('fff', 100);
$white = $palette->color('ffffff', 100);
$white = $palette->color('#fff', 100);
$white = $palette->color('#ffffff', 100);
$white = $palette->color(0xFFFFFF, 100);
$white = $palette->color(array(255, 255, 255), 100);
复制代码

color方法有两个参数

  • 颜色值
  • 透明度

改变模式

这个需求你可能很少遇见但是它存在,我们将一个图片从CMYK模式改为RGB模式,可以如下操作。

$image = $imagine->open('my-cmyk-jpg.jpg');
$image->usePalette(new ImagineImagePaletteRGB())->save('my-rgb-jpg.jpg');
复制代码

注意

这里需要注意,不同的驱动对颜色的支持有所区别

  • GD仅支持RGB图像。
  • Imagick支持CMYK,RGB和灰度色彩空间。
  • Gmagick仅支持CMYK和RGB色彩空间。

图层的概念经常出现在作图软件中,比如PS软件导出PSD文件,还有就是gif格式的图片,Imagine通过其layers方法提供了此功能。

注意 并不是所有的库都支持图层,比如GD库就不支持,因此如果你想使用图层请不要选择它。

关于图层我在这里并不打算做详细的讲解,一来这是进阶内容,二来使用图层生成动画操作并不常用,不过有些操作依然很有用,那就是图层的读取,比如你想抽取一个gif动图的某一层,甚至包含对一些多图层图片的数据分析,使用imagine更加适合。

常用方法

得到一个图片图层的数量

$image = $imagine->open('image.jpg');
echo "Image contains " . count($image->layers()) . " layers";
复制代码

循环每个图层

$image = $imagine->open('image.jpg');
foreach ($image->layers() as $layer) {// ...
}
复制代码

导出gif动画的每一层为图片

$i = 0;
foreach ($imagine->open('cats.gif')->layers() as $layer) {$layer->save("frame-$i.png");$i++;
}
复制代码

给一个gif文件每一层添加文本

$image = $imagine->open('cats.gif');
$i = 0;
foreach ($image->layers() as $layer) {$layer->draw()->text($i, new Font('coolfont.ttf', 12, $image->palette()->color('white')), new Point(10, 10));$i++;
}// save modified animation
$image->save('cats-modified.gif', array('flatten' => 'false'));
复制代码

Imagine还提供功能齐全的特效API。要使用api,您需要使用ImageInterface::effects()方法从当前图像实例获取效果实例。

我们先来一个最简单的例子

$imagine = new Imagine();
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->grayscale();
复制代码

套路都是一样的,通过$image->effects()获得Effects类对象,然后执行一些列特效方法,而无论是GD、Imagick还是Gmagick库的Effects类都是对 Imagine/Effects/EffectsInterface.php 接口的实现。

支持的特效

Imagine支持5中图片效果,我们一个一个说。

gamma

gamma在平时是不常用的,只有在专业的图像领域才会使用,可以理解为色阶,是灰阶亮度值与灰阶等级之间的数学关系。

这里的Gamma功能是校正图像色阶,使得图像看起来颜色更加正确。数字值取值范围只有最小值没有最大值只要 >=1.0都可以。

$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->gamma(2.0);
复制代码

negative

在数码相机时代之前,占统治地位的是胶卷相机,胶卷底片与洗出来的相片相比,底片的RGB值就是相片的RGB值取反,即:底片的红色=255-相片的红色,底片的绿色=255-相片的绿色,底片的蓝色=255-相片的蓝色。

$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->negative();
复制代码

grayscale

使用Grayscale使图片所有的色彩丢弃,只保留黑白两种颜色,没有取值。

$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->grayscale();
复制代码

colorize

使用colorize参数,调整图片的红绿蓝三个基础色来改变图片颜色。

此功能仅适用于Gd和Imagick驱动程序。

$imagine = new Imagine();
$p = new RGB();
$color = $p->color("#FF6900");
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->colorize($color);
复制代码

sharpen

图片锐化就是补偿图像的轮廓,增强图像的边缘及灰度跳变的部分,使图像变得清晰。

$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->sharpen();
复制代码

blur

模糊化一张图片

$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()->blur(3);
复制代码

注意

请注意,很多方法有库的差别,请小心,另外以上特效方法可以组合使用。

阿北哥ya的网站 nai8.me

Imagine中文文档相关推荐

  1. PyTorch官方中文文档:torch.optim 优化器参数

    内容预览: step(closure) 进行单次优化 (参数更新). 参数: closure (callable) –...~ 参数: params (iterable) – 待优化参数的iterab ...

  2. golang中文文档_Golang 标准库 限流器 time/rate 设计与实现

    限流器是后台服务中十分重要的组件,在实际的业务场景中使用居多,其设计在微服务.网关.和一些后台服务中会经常遇到.限流器的作用是用来限制其请求的速率,保护后台响应服务,以免服务过载导致服务不可用现象出现 ...

  3. springboot中文文档_登顶 Github 的 Spring Boot 仓库!艿艿写的最肝系列

    源码精品专栏 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 My ...

  4. Apache Spark 2.2.0 中文文档 翻译活动

    为什么80%的码农都做不了架构师?>>>    Spark 2.2.0 已然发布(2017-07-11 发布) 5 天了,更新了一些新套路吧! 此版本从 Structured Str ...

  5. Python爱好者周知:Scikit-Learn中文文档正式发布

    整理 | 费棋 出品 | AI科技大本营(公众号ID:rgznai100) 近日,Scikit-Learn 中文文档已由开源组织 ApacheCN 完成校对.该中文文档依然包含了 Scikit-Lea ...

  6. GitHub 中文文档正式发布

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 中国作为全球最大的人口大国,所属开发者在 GitHub 上的占比自 ...

  7. 推荐:Webpack2入门到深入的中文文档

    2019独角兽企业重金招聘Python工程师标准>>> 最近看了一本不错的<<webpack2中文文档>>的PDF,对比于wepack2官网(https:// ...

  8. matlab中文文档_Linux下Matlab安装

    如果觉得文章好看,欢迎点赞.同时欢迎关注微信公众号:氷泠之路. 引言 抱歉国庆由于各种原因一直没空更新文章,啊啊啊啊啊.... 因为在忙各种各样的事情,都怪女朋友,另外也更新了"装备&quo ...

  9. 使用编译器——Solidity中文文档(8)

    写在前面:HiBlock区块链社区成立了翻译小组,翻译区块链相关的技术文档及资料,本文为Solidity文档翻译的第八部分<使用编译器>,特发布出来邀请solidity爱好者.开发者做公开 ...

  10. Android 3.0 r1 API中文文档(107) —— AsyncPlayer

    一.结构 public class AsyncPlayer extends Object java.lang.Object android.media.AsyncPlayer 二.概述 播放一个连续( ...

最新文章

  1. 【干货】前端自学之路(持续更新)
  2. Alamofire 的使用
  3. linux搜索文件为1kb,Linux常用命令
  4. Oracle数据处理
  5. 编程获取linuxservercpu、内存和磁盘使用
  6. 进程共享变量#pragma data_seg用法
  7. LeetCode 500. Keyboard Row
  8. 纯CSS实现的滑动的可折叠菜单
  9. Uber发布的CoordConv遭深度质疑,“翻译个坐标也需要训练?”
  10. [swift] LeetCode 136. Single Number
  11. Ajax 读取.ashx 返回404
  12. iOS项目之wifi局域网传输文件到iPhone的简单实现
  13. vue-cli webpack配置注释
  14. 【毕业季·进击的技术er】大学生计算机毕业设计应该这样写
  15. 图片拼图微信小程序源码下载支持多模板制作和流量主
  16. 改变ros bag 中消息的frame_id 和话题名
  17. OPUS进行音频编码与解码
  18. 陈宇(Aqua)-安全->云安全->多云安全
  19. 在谷歌浏览器中自动翻译文本
  20. 国内终端安全防护市场报告发布 360网神排行第一

热门文章

  1. Gate.io 土耳其社区与 Casper AMA圆满完成,共话Casper未来发展
  2. Week 8 CSP M2 HRZ学英语
  3. [摘]PKM:个人知识管理
  4. 皮皮虾视频分析并加工
  5. oracle配置安全更新失败,安装Oracle11gR2先决条件检查失败的详细解决处理过程
  6. 基于内容推荐算法详解(比较全面的文章)
  7. 解决Vue项目: verbose stack Error: unable to resolve dependency tree
  8. HBuilder升级失败,/HBuilder/plugins 被另—个程序占用,请退出占用程序或者重启计算机后重试
  9. python爬虫——百度文本审核技术
  10. 从鹿晗关晓彤恋情事件看运维的节假日准备工作