Imagine中文文档

栏目: PHP · 发布时间: 6年前

内容简介:很多PHPER在处理图片库的时候都会选择Imagine,不过这个库只有英文文档,昨日翻译一下,送给需要的同学。Imagine是一个PHP5.3+的图片处理库,对于图片的处理可以使用GD2、Imagick或Gmagick。Imagine具有强大的功能和简洁的API接口,众多PHP框架都采用Imagine来完成对图片的操作。

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

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库的目录结构

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方法得到基本的元数据,看看输出数据的解构。

Imagine中文文档

通过结果我们看到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扩展,否则会有如下报错。

Imagine中文文档

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

自定义

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

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

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

坐标系统

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

Imagine中文文档

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

相关类

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

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

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

Imagine中文文档

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的实现思路。

  • 首先我们要使用 $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);
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Concurrency on the JVM

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》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具