不少PHPER在处理图片库的时候都会选择Imagine,不过这个库只有英文文档,昨日翻译一下,送给须要的同窗。php
Imagine具备强大的功能和简洁的API接口,众多PHP框架都采用Imagine来完成对图片的操做。html
目前为止Imagine能实现功能以下web
可使用composer方便的进行Imagine安装,以下代码api
php composer.phar require imagine/imagine
复制代码
在这一章咱们使用Imagine完成一些有趣的事情,经过这些事情你能够熟悉Imagine的使用流程。composer
咱们先来熟悉一下Imagine库的目录结构框架
上面目录具体干的事情以下ide
不要被这么多目录所迷惑,Imagine是一个设计很是清晰及现代的图片库,支持了主流的底层库,扩展性很是强,做者为了后期扩展方便提供了几个基础接口来撑起Imagine。学习
它们分别是动画
这里面最重要的是 ImagineInterface 和 ImageInterface 。网站
ImagineInterface是Imagine的核心,一块儿从它开始,它存在于 Imagine/Image/ImagineInterface.php ,固然这是一个接口,针对Gd、Imagick和Gmagick不一样的库,在对应文件夹的 Imagine.php 文件对此接口进行了实现,具体位置请看下面列表。
ImagineInterface就像一个工厂,经过ImagineInterface接口的类能够新建、打开图像,而且返回一个 ImageInterface 对象,而在 ImageInterface 提供了对图片的具体操做。
如今咱们来举一个例子
$imagine = new ImagineGdImagine();
$image = $imagine->open('/xxx/image.jpg');
复制代码
上面的例子逻辑是这样的
经过上面的ImagineInterface咱们打开了一个对象,而且获得了ImageInterface的实例化对象,ImageInterface也是一个抽象的接口,针对不一样的库有不一样的实现,它们都在叫作Image的类中,目录以下
打开任何一个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文件下内你看到了相同名称的文件。
一套接口,各类库对其进行实现,这就是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。
你可能差别元数据就这点信息么?还能够更多。
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中提供给了两个接口,分别是
分别比ImagineImage下的Box类和Point类所实现,而且被其余类所使用,好比当咱们调用$image->getSize的时候就用到。
每个坐标都有以下方法
每一个盒子或图像或形状都有一个大小,如下几种方法:
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的实现思路。
经过上面咱们知道要绘图实际上是调用了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的绘图功能到底有哪些?
对,DrawerInterface接口定义了8个方法,因此实现此接口的类都须要实现它们,绘图是最好练习Box和Point的途径,建议你多画一画。
通常来讲,当咱们使用Imagine时涉及到了颜色,不会直接传递颜色值,而是传递一个Palette对象,好比下面的例子。
$palette = new ImagineImagePaletteCMYK();
$imagine->create(new ImagineImageBox(10, 10), $palette->color('#FFFFFF'));
复制代码
Imagine提供了两个类,RGB和CMYK。
使用上首先调用响应的类,实例化
$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');
复制代码
这里须要注意,不一样的驱动对颜色的支持有所区别
图层的概念常常出如今做图软件中,好比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功能是校订图像色阶,使得图像看起来颜色更加正确。数字值取值范围只有最小值没有最大值只要 >=1.0均可以。
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()
->gamma(2.0);
复制代码
在数码相机时代以前,占统治地位的是胶卷相机,胶卷底片与洗出来的相片相比,底片的RGB值就是相片的RGB值取反,即:底片的红色=255-相片的红色,底片的绿色=255-相片的绿色,底片的蓝色=255-相片的蓝色。
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()
->negative();
复制代码
使用Grayscale使图片全部的色彩丢弃,只保留黑白两种颜色,没有取值。
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()
->grayscale();
复制代码
使用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);
复制代码
图片锐化就是补偿图像的轮廓,加强图像的边缘及灰度跳变的部分,使图像变得清晰。
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()
->sharpen();
复制代码
模糊化一张图片
$image = $imagine->open(Yii::getAlias("@webroot")."/images/qrcode.jpeg");
$image->effects()
->blur(3);
复制代码
请注意,不少方法有库的差异,请当心,另外以上特效方法能够组合使用。
阿北哥ya的网站 nai8.me