内容简介:很多PHPER在处理图片库的时候都会选择Imagine,不过这个库只有英文文档,昨日翻译一下,送给需要的同学。Imagine是一个PHP5.3+的图片处理库,对于图片的处理可以使用GD2、Imagick或Gmagick。Imagine具有强大的功能和简洁的API接口,众多PHP框架都采用Imagine来完成对图片的操作。
很多PHPER在处理图片库的时候都会选择Imagine,不过这个库只有英文文档,昨日翻译一下,送给需要的同学。
Imagine是一个 PHP 5.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
- ....
这里面最重要的是 ImagineInterface 和 ImageInterface 。
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); 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 觅道文档 v0.6.0 发布,在线文档系统
- 一个适合程序员的 Markdown 文档编辑和文档管理方案
- 【微服务】如何优雅的写文档(文档自动化swagger)
- 利用Python3内置文档资源高效学习及官方中文文档
- 什么是 API 文档工具?附带 6 款好用的 API 文档工具介绍
- VirAPI 接口文档导出功能上线,可分享并离线查看接口文档啦!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming Concurrency on the JVM
Venkat Subramaniam / The Pragmatic Bookshelf / 2011-6-1 / USD 35.00
Concurrency on the Java platform has evolved, from the synchronization model of JDK to software transactional memory (STM) and actor-based concurrency. This book is the first to show you all these con......一起来看看 《Programming Concurrency on the JVM》 这本书的介绍吧!