Imagine中文文檔

不少PHPER在處理圖片庫的時候都會選擇Imagine,不過這個庫只有英文文檔,昨日翻譯一下,送給須要的同窗。php

Imagine是一個PHP5.3+的圖片處理庫,對於圖片的處理可使用GD二、Imagick或Gmagick。

能實現什麼

Imagine具備強大的功能和簡潔的API接口,衆多PHP框架都採用Imagine來完成對圖片的操做。html

目前爲止Imagine能實現功能以下web

  • 圖片的大小調整及裁剪等操做。
  • 繪圖,建立基本圖形和高級圖表。
  • 蒙版功能,實現圖像的半透明或絕對透明功能。

安裝Imagine

可使用composer方便的進行Imagine安裝,以下代碼api

php composer.phar require imagine/imagine
複製代碼

在這一章咱們使用Imagine完成一些有趣的事情,經過這些事情你能夠熟悉Imagine的使用流程。composer

目錄結構

咱們先來熟悉一下Imagine庫的目錄結構框架

上面目錄具體乾的事情以下ide

  • 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庫
  • 使用 imagine 的open方法打開本地的一張jpg圖片,而且返回一個圖片對象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)- 返回BoxInterface每一個邊乘以的新實例ratio
  • increase(size)- 返回一個新的BoxInterface,並size添加給每一方
  • contains(BoxInterface box, PointInterfacestart = null)-檢查給定box包含在該當前內部BoxInterface在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

相關文章
相關標籤/搜索