EvaThumber:基于URL的圖片處理庫 (可實現縮略圖 | 二維碼 | 水印 | 面部識別等)
EvaThumber 是一個基于URL的輕量級圖片處理庫,支持縮放/旋轉/截取/濾鏡等多種常用圖片處理,支持設置水印/二維碼,并且可以進行面部識別以及PNG優化壓縮,所有處理僅僅需要通過更改圖片的URL。
EvaThumber基于PHP實現,可以一鍵安裝在任何主流系統,由于基于URL實現接口,所以其他編程語言也可以使用EvaThumber作為前端組件。
EvaThumber is a url based image transformation php library. See English version document.
EvaThumber的源代碼存放于Github,完全開源,歡迎Fork或關注我。
下面是幾個實例:
原圖:
http://evathumber.avnpc.com/upload/demo.jpg
EvaThumber的處理:裁剪為寬100,高100,加黑白濾鏡,輸出為png格式
http://evathumber.avnpc.com/thumb/d/demo,c_fill,f_gray,h_100,w_100.png
按寬度縮小到150px,旋轉180度,加上水印,壓縮質量為60%。
http://evathumber.avnpc.com/thumb/watermark/demo,q_60,r_180,w_150.jpg
使用二維碼作為水印,水印放在圖片中央,縮小到原圖的50%
http://evathumber.avnpc.com/thumb/watermark2/demo,p_50.jpg
在項目初期原型設計時,想要做一個圖片墻功能,一般需要一些高質量的圖片作為素材先看看效果,還在為一張一張找然后一張一張裁剪而感到厭煩?
EvaThumber只需要直接書寫HTML,高素質的圖片會自動下載并剪裁為指定尺寸展示出來:
<div style="max-width:800px;" class="thumbnails"> <div class="span4"><a class="thumbnail" href="#"><img src="https://simg.open-open.com/show/4b4fa39392fc2833bcd366b14729ba93.jpg"></a></div> <div class="span3"><a class="thumbnail" href="#"><img src="https://simg.open-open.com/show/9b7a5df473996b499626f13e1be1e6f4.jpg"></a></div> <div class="span2"><a class="thumbnail" href="#"><img src="https://simg.open-open.com/show/f53aff3c73b028e76304388e418aaebe.jpg"></a></div> <div class="span3"><a class="thumbnail" href="#"><img src="https://simg.open-open.com/show/6739ed4f0d8ff0ece367fba27691d545.jpg"></a></div> <div class="span2"><a class="thumbnail" href="#"><img src="https://simg.open-open.com/show/306e59b3c9e031fcae4f2f08e9175ab4.jpg"></a></div> </div>
為什么用EvaThumber
- 一切基于URL,人人可用,任何項目均可集成
- 所見即所得,前端人員無痛調試
- 設計人員在項目前期大量圖片素材自動獲取
- 同時支持GD/Imagick/Gmagick三大主流圖片處理庫,幾乎可在所有服務器上部署
- 面部識別/水印/PNG優化壓縮等更多有趣功能
基本功能 (URL API)
URL基本構成
一個典型的EvaThumber的URL形如:
http://evathumber.avnpc.com/thumb/default/abc/demo,c_fill,w_100,h_100.gif
高亮的部分分別是:
- 前綴 prefix 可在配置文件中設置,一般是緩存存放的文件夾名
- 配置文件名 configKey 因為一個EvaThumber可以對應多組配置文件,這里用來區分當前正在使用哪一組配置。
- 圖片路徑 根據圖片路徑才能找到源文件,如果是壓縮包內文件也需要完整的路徑
- 操作參數 多個參數以逗號分隔,參數內以下劃線區別參數名和值
- 輸出格式 更改文件擴展名即可更改圖片輸出格式
舉例說明,我們的配置文件為:
'thumbers' => array(
'default' => array(
'source_path' => '/usr/www/upload',
'prefix' => 'thumb',
),
'another' => array(
'source_path' => '/usr/www/another',
),
),
此時訪問
http://evathumber.avnpc.com/thumb/default/abc/demo,c_fill,w_100,h_100.gif
首先會找到配置文件的default
片段,然后在/usr/www/upload/abc
下查找文件名為demo
的圖片文件。
同理
http://evathumber.avnpc.com/thumb/another/foo.png
會搜索/usr/www/another
下的foo.*
文件
影子模式
很多時候我們不希望暴露原圖片的地址,此時可以通過EvaThumber自動生成原圖片的影子圖片,保護原圖片URL不被泄露,比如
- 原圖片地址為 : http://evathumber.avnpc.com/upload/demo.jpg
- 影子圖片地址為 : http://evathumber.avnpc.com/thumb/d/demo.jpg,在網站中只需要公布影子圖片即可
假如原圖片位于多級的樹形目錄下,影子圖片也會保持與原圖片同樣的目錄結構,從原切換到影子只需要更改域名或者根目錄。
圖片尺寸限制
如果圖片由用戶上傳,那么可能會遇到非常大的圖片,此時可以在配置文件中設置最大尺寸限制。比如
'thumbers' => array(
'max' => array(
'max_width' => 100,
'max_height' => 100,
),
),
訪問當前配置下的圖片,圖片寬度已經被限制為100:
http://evathumber.avnpc.com/thumb/max/demo.jpg
圖片格式轉換
EvaThumber支持的圖片格式有:
- GIF (Graphics Interchange Format)
- JPEG
- PNG (Portable Network Graphics)
- WBMP (Wireless Application Protocol Bitmap Format)
- XBM (X BitMap)
支持在任意兩種格式間轉換,只需要更改URL最后的擴展名即可,比如
http://evathumber.avnpc.com/thumb/d/demo,w_100.gif http://evathumber.avnpc.com/thumb/d/demo,w_100.xbm
圖片縮放
根據寬度縮放 w_[int Width]
:
w_
允許輸入一個整數,控制圖片按寬度縮放,下面的URL會生成一張100px寬的圖片:
http://evathumber.avnpc.com/thumb/d/demo,w_100.jpg
根據高度縮放 h_[int Height]
:
同理h_
允許輸入一個整數,控制圖片按高度縮放,下面的URL會生成一張50px高的圖片:
http://evathumber.avnpc.com/thumb/d/demo,h_50.jpg
按百分比縮放 p_[int Percent]
:
p_
允許輸入一個1-100的數字,圖片會按照百分比縮放,比如p_30會將圖片縮放至原尺寸的30%:
http://evathumber.avnpc.com/thumb/d/demo,p_30.jpg
允許拉伸:
在縮放圖片時,如果縮放尺寸大于圖片本身的尺寸,操作默認會被忽略,但是也可以在配置文件中強制開啟
'thumbers' => array(
'stretch' => array(
'allow_stretch' => true,
),
),
此時圖片允許被強制拉伸。
http://evathumber.avnpc.com/thumb/stretch/demo,w_310.jpg
圖片剪裁
基本正方形剪裁 c_[int Crop]
:
c_
允許輸入一個整數,如c_50
會從圖片的中心位置截取出一張50px*50px的縮略圖。
http://evathumber.avnpc.com/thumb/d/demo,c_50.jpg
指定尺寸的剪裁 c_[int Crop]
+ g_[int Gracity]
:
配合c_
輸入g_
,代表指定剪裁的寬度與高度,比如c_50,g_30
,代表從圖片中心位置剪裁一張50px*30px的縮略圖。
http://evathumber.avnpc.com/thumb/d/demo,c_50,g_30.jpg
指定坐標 x_[int X]
+ y_[int y]
:
如果想要指定剪裁的精確位置,需要用x_
和y_
參數指定起點坐標,x_0,y_0
以圖片左上角為坐標原點。
比如 c_50,g_60,x_40,y_30
代表以距離圖片左邊40px,上邊30px為起點,剪裁一張50px*60px的圖片。
http://EvaThumber.avnpc.com/thumb/demo,c_100,g_200,x_80,y_10.jpg
圖片的剪裁與縮放可以混用,EvaThumber始終會先進行剪裁,然后再對剪裁后的圖片縮放。
http://evathumber.avnpc.com/thumb/d/demo,c_50,g_60,x_40,y_30,w_30.jpg
填充模式 c_fill
+ w_[int Width]
+ h_[int Height]
在實際使用中,我們經常會遇到這樣的場景:需要截取并縮放圖片以適應網頁布局,此時我們可以使用剪裁中的填充模式,在填充模式下,需要指定剪裁參數為c_fill
,同時設定填充的寬度與高度,然后可以得到一張完全吻合設定尺寸,同時經過縮放與剪裁處理的圖片。
http://evathumber.avnpc.com/thumb/d/demo,c_fill,w_50,h_50.jpg
圖片旋轉 r_[int Rotate]
r_
允許指定一個1-360的數字作為圖片旋轉的角度,比如r_90
讓圖片按照順時針旋轉90度:
http://evathumber.avnpc.com/thumb/d/demo,r_90,w_50.png
圖片濾鏡 f_[string Filter]
目前支持的濾鏡有:
f_gray
黑白濾鏡
圖片壓縮質量 q_[int Quality]
q_
允許指定一個1-100的參數設置jpg圖片的壓縮質量:
http://evathumber.avnpc.com/thumb/d/demo,w_100,q_10.jpg
也可以在配置文件中設置一個全局壓縮質量:
'thumbers' => array(
'd' => array(
'quality' => 70,
),
),
圖片水印
圖片水印
可以在配置文件中指定layer_file
為一張圖片作為水印:
'thumbers' => array(
'd' => array(
'watermark' => array(
'enable' => 1,
'position' => 'br',
'layer_file' => __DIR__ . '/layers/watermark.png',
),
),
),
水印的位置可以在:
tl
: Top Left 左上tr
: Top Right 右上bl
: Bottom Left 左下br
: Bottom Right 右下center
: 中央
文字水印
同樣可以直接使用文字作為水印
'thumbers' => array(
'd' => array(
'watermark' => array(
'enable' => 1,
'position' => 'br',
'layer_file' => '',
'text' => 'EvaThumber',
'font_file' => __DIR__ . '/layers/Yahei_Mono.ttf',
'font_size' => 12,
'font_color' => '#FFFFFF',
),
),
),
此時必須將layer_file
指定為空,同時設置:
font_file
: 水印使用的ttf字體文件font_size
: 字體大小font_color
: 字體顏色text
: 文字內容
如果文字中包含中文等字符,需要ttf字體包含該字符集,否則可能出現亂碼。
水印會在最后添加上去,不會受圖片縮放旋轉的影響。
擴展功能
二維碼水印
作為擴展功能,二維碼水印暫時只采用GD庫生成,需要配置以下項目:
'thumbers' => array(
'd' => array(
'watermark' => array(
'enable' => 1,
'position' => 'center',
'layer_file' => '',
'text' => 'http://avnpc.com/pages/evathumber',
'qr_code' => 1,
'qr_code_size' => 2,
'qr_code_margin' => 1,
),
),
),
qr_code
是否啟用二維碼 1/0qr_code_size
二維碼大小qr_code_margin
二維碼內邊距
自動素材
通過設置d_dummy
可以自動獲得優質的圖片素材,EvaThumber內置了兩個默認圖片源:
當自動素材功能啟用時,圖片路徑可隨意填寫:
http://evathumber.avnpc.com/thumb/d/foo,c_fill,d_picasa,h_100,w_100.jpg
http://evathumber.avnpc.com/thumb/d/bar,c_fill,d_flickr,h_100,w_100.jpg
讀取壓縮包
如果在配置文件中指定source_path
為一個ZIP壓縮包文件,則可以直接從壓縮包中讀取圖片信息無需解壓。比如
'thumbers' => array(
'zip' => array(
'source_path' => __DIR__ . '/upload/archive.zip',
'zip_file_encoding' => 'GB2312',
),
),
如果壓縮包中路徑或文件名含有非英語字符,則需要指定壓縮包壓縮時的系統編碼,一般來說中文系統需要指定為GB2312
。
如壓縮包內文件結構為
- archive.zip
- archive/
zipimage.jpg
中文.jpg
訪問
http://evathumber.avnpc.com/thumb/zip/archive/zipimage,w_100.jpg
http://evathumber.avnpc.com/thumb/zip/archive/中文,w_100.jpg
面部識別
剪裁圖片時默認的方式是通過指定x_
和y_
坐標來選擇剪裁的區域,不過如果是帶有人物的圖片,可以試試使用c_face
去自動識別人物面部坐標,比如下圖
http://evathumber.avnpc.com/thumb/d/face,w_100.jpg
使用默認的剪裁方式:
http://evathumber.avnpc.com/thumb/d/face,c_100.jpg
使用面部識別:
http://evathumber.avnpc.com/thumb/d/face,c_face,w_100,h_100.jpg
PNG圖片優化
EvaThumber可以對PNG圖片進行無損優化,優化基于PNGOut項目,下載pngout.exe到bin文件夾,配置以下項目:
'thumbers' => array(
'png' => array(
'png_optimize' => array(
'enable' => 1,
'pngout' => array(
'bin' => __DIR__ . '/bin/pngout.exe',
),
),
),
),
對比一下有無圖片優化的效果:
58.8K
26.5K
安全問題
圖片的動態生成,在實際部署上可能會帶來兩方面的問題:
- 如果開啟緩存,那么每一張圖片可能會有無數種排列組合,如果被惡意請求,很可能短時間內產生大量文件把磁盤塞滿。
- 圖片處理比較吃內存和CPU,在高并發環境下,服務器性能可能無法跟上。
對于問題1,EvaThumber采用如下的方法應對:
URL唯一化
EvaThumber對于同樣操作的請求,以及帶有多余參數的請求,都會被重定向到唯一的一個URL地址,比如
http://evathumber.avnpc.com/thumb/d/demo,w_1000.jpg
寬度超出http://evathumber.avnpc.com/thumb/d/demo,x_10.jpg
不必要參數http://evathumber.avnpc.com/thumb/d/demo,,,,.jpg
錯誤參數
等等情況,都會被重定向到唯一的URLhttp://evathumber.avnpc.com/thumb/d/demo.jpg
。從而保證緩存盡可能少的產生。
設置允許尺寸
在大部分Web應用中,其實圖片都會被縮放為固定的幾個尺寸,所以可以在配置文件中指定允許被縮放的尺寸:
'thumbers' => array(
'd' => array(
'allow_sizes' => array(
'200*100',
),
),
),
此時圖片只允許被縮放為w_200,h_100
設置禁止操作
EvaThumber所提供的功能并不一定能全部用到,可以在配置文件中禁用某些操作
'thumbers' => array(
'd' => array(
'disable_operates' => array(
'filter',
'rotate',
'dummy',
),
),
),
可以禁用的操作包括:
- 'crop' 剪裁
- 'dummy' 自動素材
- 'filter' 濾鏡
- 'gravity' 剪裁范圍
- 'height' 按高度縮放
- 'percent' 按百分比縮放
- 'quality' 壓縮質量
- 'rotate' 旋轉
- 'width' 按寬度縮放
- 'x' 選取剪裁位置
- 'y' 選取剪裁位置
- 'extension' 更改輸出格式
在正式環境中,可以同時設置允許尺寸以及禁用操作。典型的場景如用戶上傳頭像,配置文件設置為:
'thumbers' => array(
'd' => array(
'max_width' => 300,
'max_height' => 300,
'allow_sizes' => array(
'200*200',
'100*100',
'50*50',
),
'disable_operates' => array(
'dummy',
'filter',
'gravity',
'percent',
'quality',
'rotate',
'x',
'extension',
),
),
),
此時一張圖片最多產生原圖+3個尺寸的縮略圖,已經不需要特別做安全設置了。
高并發環境下的部署建議
在高并發環境下,不建議直接暴露EvaThumber給最終用戶。推薦的方式是配合一個消息隊列,在后臺運行EvaThumber生成項目所需要的所有規格縮略圖,來看一個實際的例子:
- 假設EvaThumber部署在
/usr/www/EvaThumber
- 綁定一個內網域名evathumber.local到
/usr/www/EvaThumber
,此域名只有服務器之間能訪問,外網無法訪問 - 將用戶上傳圖片路徑指定為
/usr/www/EvaThumber/upload
- 用戶上傳圖片demo.jpg到
/usr/www/EvaThumber/upload/demo.jpg
- 開啟EvaThumber緩存,緩存路徑指定為
/usr/www/EvaThumber/thumb
,同時向消息隊列發送消息,消息的內容都是EvaThumber URL,如http://evathumber.local/thumb/d/demo,w_100.jpg
- 運行消息隊列,因為每一條消息都是一個URL,可以用cURL直接訪問。此時會生成緩存
/usr/www/EvaThumber/thumb/demo,w_100.jpg
- 綁定外網可以訪問的域名如evathumber.avnpc.com到
/usr/www/EvaThumber/thumb
- 用戶可以通過
http://evathumber.avnpc.com/demo,w_100.jpg
訪問到最終結果。
安裝與設置
快速開始
在Linux下,用4行命令完成安裝,假設web服務器目錄為/opt/htdocs
。
cd /opt/htdocs
git clone git://github.com/AlloVince/EvaThumber.git cd EvaThumber
composer install
然后訪問http://localhost/EvaThumber/index.php/thumb/d/demo.jpg
即可看到示例的Demo圖片并進行操作了。
安裝基礎功能
基礎功能包括:
- 圖片縮放/剪裁/旋轉等基礎操作
- 圖片濾鏡
- 水印 (文字水印與圖片水印)
如果已經有Composer,再EvaThumber目錄下直接運行即可支持基礎功能:
composer install
如果沒有安裝Composer,參考下文:
Windows下安裝Composer
假設php.exe目錄在d:\xampp\php,那么首先將php目錄加入windows環境變量。
cd d:\xampp\php
php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
同目錄下編輯文件 composer.bat,內容為
@ECHO OFFSET composerScript=composer.phar
php "%~dp0%composerScript%" %*
運行
composer -V
檢查composer安裝是否成功。
Linux下安裝Composer
以Ubuntu為例
apt-get install curl
cd /usr/local/bin
curl -s http://getcomposer.org/installer | php chmod a+x composer.phar
alias composer='/usr/local/bin/composer.phar'
開啟URL Rewirte
開啟URL Rewirte之后,可以省略URL中的index.php
部分,如果已經生成緩存,則會優先顯示緩存,所以在生產環境中是必須要打開的。
Apache開啟URL Rewirte
如果服務器為Apache并且已經開啟mod_rewrite模塊,則無需任何設置,重寫規則已經寫入.htaccess文件。
Nginx開啟URL Rewirte
請參考以下配置調整路徑
server {
listen 80;
server_name evathumber.avnpc.com;
location / {
root /usr/www/EvaThumber/;
index index.php index.html index.htm;
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php last;
}
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/www/EvaThumber/$fastcgi_script_name;
}
}
配置文件復寫
因為配置文件可能經常需要修改,如果采用了GIT或SVN這樣的版本控制工具非常容易引起沖突,所以這里并不推薦直接編輯config.default.php
文件。
推薦的方法是新建一個config.local.php
文件放于EvaThumber目錄下,內容則與config.default.php
保持同樣的結構,所有的項目會自動復寫默認設置。
開啟緩存
緩存啟用依賴于URL Rewrite已經啟用。對于每一組配置文件,都可以通過'thumb_cache_path'
指定一個緩存放置的路徑,同時將該組的'cache'
設置為1。
以上文的Nginx配置為例
'thumbers' => array(
'd' => array(
'thumb_cache_path' => '/usr/www/EvaThumber/thumb',
'cache' => 1,
),
),
緩存開啟后,需要把URL中的index.php/
部分去掉。
http://evathumber.avnpc.com/index.php/thumb/d/demo,w_100.jpg
需要更改為:
http://evathumber.avnpc.com/thumb/d/demo,w_100.jpg
用戶第一次訪問時,Nginx會將請求重寫到index.php
并生成緩存;當用戶第二次訪問時,會由Nginx優先命中/usr/www/EvaThumber/thumb/d/demo,w_100.jpg
,不會訪問到php。
安裝擴展功能
擴展功能包括:
- 二維碼水印
- 隨機素材
- 面部識別
- PNG壓縮
除面部識別以外,只需要運行
composer install --dev
如果已經安裝了基礎功能,運行
composer update --dev
面部識別功能安裝
面部識別基于OpenCV項目,可以參考官方網站的OpenCV安裝指南安裝。
EvaThumber用Python實現了一個輕量Hook,在bin/opencv.py
下,也可以在配置文件中指定路徑
'thumbers' => array(
'd' => array(
'face_detect' => array(
'enable' => 0,
'draw_border' => 1,
'cascade' => '',
'bin' => __DIR__ . '/bin/opencv.py',
),
),
),
可配置的選項包括
'draw_border'
: 是否繪制判定面部的邊線'cascade'
: 這里指定一個OpenCV的Haar CascadeXML文件的位置,OpenCV已經在源代碼的data
下提供了很多組,當然也可以自己做特征訓練制作特殊的Haar Cascade'bin'
: OpenCV Python Hook的位置
PNGOut安裝
Windows下,直接下載PNGOut.exe放置于bin目錄下。
Linux下載PNGOUT的Linux版本,解壓后在配置文件中配置pngout的路徑即可。
wget http://static.jonof.id.au/dl/kenutils/pngout-20130221-linux.tar.gz tar -xvf pngout-20130221-linux.tar.gz
解壓后可以看到針對各種CPU的不同編譯版本,一個簡單判別的方法是進入各目錄直接運行
./pngout -h
如果有輸出則支持當前CPU