一起學習PHP中GD庫的使用(二)

在日常的開發過程中,GD 庫最常用的功能就是幫我們對圖片進行一些處理,當然,除了處理已有的圖片之外,它也可以直接來畫圖,就像我們最常見的圖片驗證碼。今天的內容主要就是和畫圖有關,所以最後我們也會做一個非常簡單的圖片驗證碼的例子。

創建圖片並指定顏色

首先,我們要先創建一個圖片的畫布。就和 PhotoShop 一樣,任何的繪圖都要在一張畫布下進行。

// 創建一個 200X200 的圖像
$img = imagecreatetruecolor(200, 200);
// 分配顏色
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
$red = imagecolorallocate($img, 255, 0, 0);

// 帶透明通道的顏色
$alphaRed = imagecolorclosestalpha($img, 255, 0, 0, 50);

imagecreatetruecolor() 函數就是用於創建一個真彩色圖片,它和 imagecreate() 的區別就在於 imagecreate() 創建的是一張基於調色板的圖片。它們爲畫布填充顏色的流程不一樣,imagecreate() 不需要使用 imagefill() 進行填充背景色,直接使用 imagecolorallocate() 就會以第一次調用的 imagecolorallocate() 的顏色進行填充。它們返回的圖片文件句柄都是後期操作所需要的句柄對象。

imagecolorallocate() 就是爲圖片分配顏色,這裏我們定義了幾種顏色,另外還使用 imagecolorclosestalpha() 定義了一個帶通道的也就是還透明效果的顏色,它的最後一個參數就是 0-100 的透明度設置。

填充背景色

接下來,由於我們使用的是 imagecreatetruecolor() ,所以我們要對畫布進行背景色的填充。

// 填充背景色
imagefill($img, 0, 0, $black);

弧線、直線、矩形

不管是畫線還是畫弧線,都只是一些簡單的函數調用。

// 畫一個白色的圓
imagearc($img, 100, 100, 150, 150, 0, 360, $white);

// 畫一條線段
imageline($img, 20, 180, 120, 120, $white);

// 填充一個帶透明的矩形
imagefilledrectangle($img, 30, 30, 70, 70, $alphaRed);

imagearc() 函數本身是用於畫弧線的,第二和第三個參數用於指定圓心的位置,第四第五個參數指定圓的寬度和高度,第六、第七個參數指定弧線的起始位置(以角度指定),最後一個參數就是指定的顏色。通過給定的從 0 到 360 度的角度,我們就畫了一個圓形出來。如果不是指定的完整的 360 度,就會是一條弧線。

直線線段的函數 imageline() 的參數就比較簡單了,第二第三個參數是起始點的座標,第四第五個參數是結束點的座標,兩個座標點一連就繪製出了一條線段。

imagefilledrectangle() 是以填充的方式繪製一個矩形,也就是說我們繪製的矩形是在內部填充了顏色的,而不是線條的描邊。它的參數座標和線段是一樣的,並且我們填充的是上面定義的帶透明效果的顏色。

當然,我們能夠直接繪製的圖形和線條還有很多。需要注意的是,帶 fill 關鍵字的基本都是填充圖形,而不帶 fill 的就是形狀線段。比如如果要一個矩形框的話,我們可以使用 imagerectangle() 來進行繪製。同理,如果要畫一個扇形塊的話,我們也可以直接使用 imagefillarc() 。更多的圖形和線段大家可以參考文檔,內容比較多,這裏就不多羅列了,今天我們主要的功能是生成一張驗證碼,只要有一個線段來做爲干擾因素就可以啦。

寫字

直接在圖片中寫字也很簡單。

$string = "I Like PHP!";

// 水平寫一個字符
imagechar($img, 5, 70, 50, $string, $red);
// 垂直寫一個字符
imagecharup($img, 3, 120, 50, $string, $red);

// 水平寫字符串
imagestring($img, 5, 70, 150, $string, $red);
// 垂直寫字符串
imagestringup($img, 3, 120, 150, $string, $red);

imagechar() 是隻寫一個字符,imagecharup() 是垂直地寫。imagestring() 則是寫字符串,而 imagestringup() 也就是垂直地寫字符串啦。它們第二個參數都是字體的大小,第三和第四個參數是開始寫字的座標起始位置。不過,使用這些函數對圖片進行內容書寫的話,最主要的一個問題就是不能指定字體,這樣在默認情況下中文是沒辦法輸出的。所以,我們一般會用另一個函數來爲圖片加上文字。

// 用 TrueType 字體向圖像寫入文本
$font = '../font/arial.ttf';
imagettftext($img, 20, 0, 11, 21, $white, $font, $string);

imagettftext() 函數,能夠通過指定的字體來向圖片添加文字內容,有了字體文件的支持,寫上去的文字也好看了很多。更主要的是,它還能方便地調整文字大小和傾斜角度。第二個參數就是指定文字的大小,第三個參數就是可以指定文字的傾斜角度,也就是我們可以旋轉文字。

生成圖片

最後,當然就是要生成並輸出圖片啦!

// 將圖像輸出到瀏覽器
header("Content-type: image/png");
imagepng($img);
// 釋放內存
imagedestroy($img);

我們的測試代碼是直接將圖片輸出到瀏覽器,所以需要指定一個文件輸出的 header 頭。使用 imagepng() 就能生成一張 PNG 格式的圖片,它還有第二個參數,如果給定了第二個參數,那麼圖片就會直接以文件形式保存到參數指定的路徑中。如果不給定這個參數的話,就會像 phpinfo() 一樣直接輸出到輸出緩衝區中,也就是直接打印內容了。最後,我們再使用 imagedestroy() 釋放掉圖片句柄解除圖片文件的內存佔用。

除了 imagepng() 之外,還有 imagejpeg() 、 imagegif() 等等一系列的圖片生成函數,大家可以自己查閱文檔學習瞭解。

說了這麼多,我們上面這一堆東西畫出來的是個啥?

小例子:簡單的驗證碼圖片

最後的小例子就是一開頭我們說過的,一個非常簡單的圖片驗證碼的生成。現在的驗證碼功能其實非常複雜了,各種形式的驗證碼都有,主要還是爲了系統的安全着想。同樣在 Composer 中也有很多現成的驗證碼組件供我們使用,其實我們並不需要自己去實現這樣的驗證碼功能的,但學習嘛,總是要接觸一下了解一下的,而且如果是一些很小的小項目的話,完全就可以自己手寫一個來練習了。

$img = imagecreatetruecolor(120, 50);
imagefill($img, 0, 0, imagecolorallocate($img, 255, 255, 255));

$colors = [
    imagecolorallocate($img, 0, 0, 0),
    imagecolorallocate($img, 255, 0, 0),
    imagecolorallocate($img, 0, 255, 0),
    imagecolorallocate($img, 0, 0, 255),
];

$chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));

for ($i = 0; $i < 10; $i++) {
    imageline(
        $img,
        random_int(0, 120),
        random_int(0, 50),
        random_int(0, 120),
        random_int(0, 50),
        $colors[array_rand($colors)]
    );
}
$font = '../font/arial.ttf';
for ($i = 0; $i < 4; $i++) {
    $char = $chars[array_rand($chars)];
    $fontSize = random_int(18, 24);
    $c = random_int(-20, 20);
    $x = $i * 26;
    if ($x == 0) {
        $x = 5;
    }
    imagettftext(
        $img, 
        $fontSize, 
        $c, 
        $x, 
        40, 
        $colors[array_rand($colors)], 
        $font, 
        $char
    );
}
header("Content-type: image/png");
imagepng($img);
imagedestroy($img);

代碼就不多做解釋了,隨機取一些字符,並且隨機生成一些線段,其它的就是我們上面文章中介紹過的函數的使用了。最後生成的圖片就是這個樣子的:

總結

不管之前有沒有自己寫過這種驗證碼的小工具,今天的內容相信都是一次系統的學習和回顧,因爲我們是按着順序從創建一張圖片畫布,到繪製線條和圖形,再到添加文字,最後生成圖片這一系列的步驟走下來的。以後不管是面試還是自己做小工具的時候,記住這條線,然後參考文檔就可以啦。畢竟這些函數的參數都還是挺長挺亂的,除非天天用,要不可真記不住。

測試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202012/source/2.一起學習PHP中GD庫的使用(二).php

參考文檔:

https://www.php.net/manual/zh/book.image.php

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章