不少PHPER在處理圖片庫的時候都會選擇Imagine,不過這個庫只有英文文檔,昨日翻譯一下,送給須要的同窗。php
Imagine是一個PHP5.3+的圖片處理庫,對於圖片的處理可使用GD二、Imagick或Gmagick。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