GD Extension 主要功能是可以對圖片做處理,簡單的有圖片縮小、放大、切割,也可以用來製作圖片,這篇文章將會實做圖片的縮小,旋轉與銳利化。
Teajs GD Extension 安裝
要使用 Teajs 前,必須先安裝 GD Library , 先去下列的載點下載:GD_2_0_33
接著用 tar 解壓縮後,在 GD/src 目前下執行指令: cmake , 跑完之後再執行 make。
經過這兩步程式編譯就算完成了,最後把 libgd.so 搬到目錄 /usr/local/lib/ , 所有的 header 檔搬到 /usr/local/include/gd/ ,再執行 sudo ldconfig 即可。
如果上面的步驟一切正常,那麼我們就可以使用 GD library 了,不過這篇文章是要介紹如何使用 Teajs 的 GD , 所以得編譯完 Teajs 的 GD Extension才行。
進入 Teajs 的資料夾 src/lib/gd/, 再執行編譯指令↓
最後編譯出 gd.so 的 Teajs extension,再將 gd.so 搬到 Teajs extension 的目錄就大功告成囉,裝好之後我們就可以快樂的用 Javascript 來畫圖囉。
Javascript GD 畫圖!
在使用 GD 之前,我先來介紹一下圖片的類型,Teajs GD Extension 有支援三種圖片型態,分別是 JPEG,PNG, GIF ,這三種都是網路常見的圖片,所以也相當的夠用。
圖片Format 有二種, TrueColor 與 Palette , Palette 這個格式只能存 256 種顏色, 是 GIF 用的格式。
TrueColor 是一種由 32 bits 存儲的圖片格式,在三原色 RGB 中各用了 8個 bits ,每一個顏色可以存的數值是 0~255 ,這樣就有 2563 種組合,另外再配上「透明度 alpha」8 bits。
『jpeg』 使用的格式是 TrueColor , 『gif』使用的格式則是 Palette ,因此 gif 只有 256 種顏色可以使用,『png』則支援 TrueColor 與 Palette。
接下來我要做一個圖片Resize 的例子
Resize 程式範例
- var Image = require('gd').Image;
- var source = "Arthas-H.jpg";
- var img = resize(source , 100,150);
- img.save(Image.PNG , "tmp.png");
- function resize(img ,to_w,to_h) {
- var pos = img.lastIndexOf('.');
- var ext = img.substring(pos+1, img.length);
- var type = Image.JPEG;
- switch(ext.toLowerCase()) {
- case 'jpeg':case 'jpg':
- type = Image.JPEG;
- break;
- case 'png':
- type = Image.PNG;
- break;
- case 'gif':
- type = Image.GIF;
- break;
- }
- var source_img = new Image(type , img);
- var w = source_img.sx();
- var h = source_img.sy();
- var image = new Image(Image.TRUECOLOR, to_w, to_h);
- var destx=0,desty=0;
- var srcx=0,srcy=0;
- image = image.copyResized(source_img, destx, desty, srcx, srcy, to_w, to_h , w , h );
- return image;
- }
在 create Image 時,我使用了 TrueColor ,並載入一張 jpeg 型態的圖片,透過 copyResized method , 縮小圖片尺寸。
接下來是教學如果旋轉圖片,這裡會用到二維的『旋轉矩陣』與『三角函數』,先來看看旋轉的結果吧。
Rotate 旋轉原理
講到旋轉,就要先提到數學的座標軸轉換,首先我定義 θ1,(x1,y1) 為已知的一個點,θ2為我要旋轉的度,旋轉後我會得到 x2,y2的新座標,注意我這邊定義的旋轉是指逆時針旋轉。
# 數學上定義的旋轉,是指用座標軸逆時針旋轉 => 座標點為順時針旋轉 ,所以算出的結果有一丁點不同。
- 圖中可以算半徑 z = x12+y12 的根號
- x2 = z × cos(θ1+θ2) = z×(cosθ1×cosθ2 - sinθ1×sinθ2)
- 因為 cosθ1 = x1/z , sinθ1 = y1/z
- 得 x2 = x1×cosθ2 - y1×sinθ2
- 一樣的算法可以求得 y2 = y1×cosθ2 + x1×sinθ2
算新座標點的位置,主要是為了計算圖片在旋轉之後,長度與寬度的改變,又因為圖片一定是長方形,左右兩邊是對稱的,所以只要算出右上角 point 的位移變化,就能得知左邊的點位移,知道點的位移後,就能得知長與寬的變化。
Rotate 圖片旋轉程式範例
- var source = "Arthas-H.jpg";
- var img = rotate(source , 10);
- img.save(Image.PNG , "tmp.png");
- function rotate(img , angle) {
- var PI = Math.PI;
- var radian = PI*angle/180;
- var pos = img.lastIndexOf('.');
- var ext = img.substring(pos+1, img.length);
- var type = Image.JPEG;
- switch(ext.toLowerCase()) {
- case 'jpeg':case 'jpg':
- type = Image.JPEG;
- break;
- case 'png':
- type = Image.PNG;
- break;
- case 'gif':
- type = Image.GIF;
- break;
- }
- var source_img = new Image(type , img);
- var w = source_img.sx();
- var h = source_img.sy();
- var p2x = w/2, p2y = h/2;
- var diffw = Math.abs((p2x*Math.cos(radian) + p2y*Math.sin(radian))) - Math.abs(p2x);
- diffw = 2* Math.abs(diffw);
- var diffh = Math.abs(( -p2x*Math.sin(radian) + p2y*Math.cos(radian))) - Math.abs(p2y);
- diffh = 2* Math.abs(diffh);
- var centerx = Math.round(w/2),centery = Math.round(h/2);
- var newH = h + diffh;
- var newW = w + diffw;
- var image = new Image(Image.TRUECOLOR, newW, newH);
- var destx=newW/2,desty=newH/2;//rotate in center
- var srcx=0,srcy=0;
- image = image.copyRotated(source_img, destx, desty, srcx, srcy, w, h , angle );
- return image;
- }
接下來看看 sharpen 『銳利化』的功能
銳利化程式範例
- var img = sharpen(source, 150);
- img.save(Image.PNG , "tmp.png");
- function sharpen(img , percent) {
- var pos = img.lastIndexOf('.');
- var ext = img.substring(pos+1, img.length);
- var type = Image.JPEG;
- switch(ext.toLowerCase()) {
- case 'jpeg':case 'jpg':
- type = Image.JPEG;
- break;
- case 'png':
- type = Image.PNG;
- break;
- case 'gif':
- type = Image.GIF;
- break;
- }
- var source_img = new Image(type , img);
- var data = source_img.sharpen(percent);
- return data;
- }