又到了一個大家非常熟悉的庫了,對于圖像圖形的處理來說,GD 庫是 PHPer 們繞不過去的一道坎。從很早很早的 CMS 或者 Discuz 時代,各類開源軟件在安裝的時候就會明確地指出 GD 庫是它們必備的一個擴展。當然,在現(xiàn)在的 PHP 版本中,相信大家也不會在編譯的時候忽略掉這個庫。不管你是為圖片加水印、生成縮略圖還是制作驗證碼圖片,都離不開 GD 庫的身影。
當然,我們還是由淺入深地學習一些 GD 庫中的常用或好玩的函數(shù)。
當前環(huán)境中的 GD 庫信息
首先,我們可以查看下當前 PHP 環(huán)境中的 GD 庫版本及支持的圖片格式信息。
var_dump(gd_info());
// array(13) {
// ["GD Version"]=>
// string(26) "bundled (2.1.0 compatible)"
// ["FreeType Support"]=>
// bool(true)
// ["FreeType Linkage"]=>
// string(13) "with freetype"
// ["GIF Read Support"]=>
// bool(true)
// ["GIF Create Support"]=>
// bool(true)
// ["JPEG Support"]=>
// bool(true)
// ["PNG Support"]=>
// bool(true)
// ["WBMP Support"]=>
// bool(true)
// ["XPM Support"]=>
// bool(false)
// ["XBM Support"]=>
// bool(true)
// ["WebP Support"]=>
// bool(true)
// ["BMP Support"]=>
// bool(true)
// ["JIS-mapped Japanese Font Support"]=>
// bool(false)
// }
gd_info() 函數(shù)可以查看到當前 GD 庫的版本信息,其它字段就是各種圖片模式的支持情況,可以看到在我的系統(tǒng)環(huán)境中,除了 XPM 這種格式不支持外,其它各種圖片格式都是正常支持的。最后一個是日文字體的支持,我們當前環(huán)境中也是沒有的。
獲取圖片基本信息
getimagesize(),獲取圖片信息的這個函數(shù),從名字上看是獲取圖片大小的一個函數(shù)但也包含一些其它的信息,而且這個函數(shù)其實和 GD 庫沒什么太大的關系,也就是說不需要 GD 庫的擴展其實這個函數(shù)也是可以使用的。
var_dump(getimagesize("../img/1.png"));
// array(6) {
// [0]=>
// int(150)
// [1]=>
// int(150)
// [2]=>
// int(3)
// [3]=>
// string(24) "width="150" height="150""
// ["bits"]=>
// int(8)
// ["mime"]=>
// string(9) "image/png"
// }
返回的結果其實非常簡單,0 和 1 分別就是圖片的寬高,2 是圖片的類型,之前的文章就講過它對應的就是 IMAGETYPE_ 常量中對應的圖片類型。3 是文字形式的圖片寬高,可以直接用于 img 標簽中,可以看出來,PHP 真的就是為了 web 而生的語言啊,連圖片大小獲取的函數(shù)都要帶個這樣的屬性回來。bits 就是圖片的 顏色比特位數(shù) 。mime 則是圖片的 MIME 類型了。
另外,getimagesize() 函數(shù)還有第二個參數(shù),這是一個引用類型的參數(shù),它將以一個關聯(lián)數(shù)組返回不同的 JPG APP 標識。也就是說,它也是針對 JPG 相關的圖片獲取一些額外的信息,其實就有點像上篇文章學習過的 EXIF 里面的信息。
var_dump(getimagesize("../img/2.jpg", $info));
// array(7) {
// [0]=>
// int(300)
// [1]=>
// int(244)
// [2]=>
// int(2)
// [3]=>
// string(24) "width="300" height="244""
// ["bits"]=>
// int(8)
// ["channels"]=>
// int(3)
// ["mime"]=>
// string(10) "image/jpeg"
// }
var_dump($info);
// array(1) {
// ["APP0"]=>
// string(14) "JFIF??"
// }
此外,我們如果是 JPG 圖片的話,還會多返回一個 channels 屬性,表示的是如果圖片是 RBG 格式的,返回的就是 3 ,如果是 CMYK 格式的,返回的就是 4 。
我們還可以使用 getimagesize() 獲得遠程文件的信息。
var_dump(getimagesize("https://upload-images.jianshu.io/upload_images/1074666-8df66a94d61cac74.png?imageMogr2/auto-orient/strip|imageView2/2/w/374/format/webp"));
// array(6) {
// [0]=>
// int(374)
// [1]=>
// int(617)
// [2]=>
// int(18)
// [3]=>
// string(24) "width="374" height="617""
// ["bits"]=>
// int(8)
// ["mime"]=>
// string(10) "image/webp"
// }
除了直接操作圖片文件之外,我們還可以直接從字符串中獲得圖片的信息。不過這些字符串一般也都是讀取到的圖片文件的二進制信息。你直接來一句真正的 Hello World 之類的字符串那打死它也解析不出來什么圖片內容的。
$data = file_get_contents('../img/1.png');
var_dump(getimagesizefromstring($data));
// array(6) {
// [0]=>
// int(150)
// [1]=>
// int(150)
// [2]=>
// int(3)
// [3]=>
// string(24) "width="150" height="150""
// ["bits"]=>
// int(8)
// ["mime"]=>
// string(9) "image/png"
// }
獲得圖片的一些信息
我們可以通過圖片的類型來獲取文件的擴展名,這個類型常量也是 IMAGETYPE_ 類型的。
var_dump(image_type_to_extension(IMAGETYPE_PNG)); // string(4) ".png"
var_dump(image_type_to_extension(IMAGETYPE_JPEG, FALSE)); // string(4) "jpeg"
image_type_to_extension() 函數(shù)有第二個參數(shù),如果設置為 false 的話,就不會加上那個 . 。
var_dump(image_type_to_mime_type(IMAGETYPE_PNG)); // string(9) "image/png"
var_dump(image_type_to_mime_type(IMAGETYPE_JPEG)); // string(10) "image/jpeg"
同樣地,也有 image_type_to_mime_type() 這個函數(shù)來獲得圖片的 MIME 信息內容。另外,還有一個函數(shù)可以獲得當前系統(tǒng)中所支持的圖片類型都有哪些。
var_dump(imagetypes()); // int(111)
額,很奇怪吧,怎么只返回了一個 111 ?其實它是保存的二進制圖片支持信息,比如如果我們想知道當前系統(tǒng)中有沒有 PNG 圖片的支持,就可以這樣使用:
var_dump(imagetypes() & IMAGETYPE_PNG); // int(3)
和 IMAGETYPE_PNG 與之后的結果就是 IMAGETYPE_PNG 本身的值,這就說明當前系統(tǒng)中是支持這個圖片類型的操作的。
小例子:創(chuàng)建一張自己的圖片
最后,我們再來看一個小例子,其實就是利用 GD 庫中的這些函數(shù)來創(chuàng)建一張簡單的小圖片。
$im = @imagecreate(100, 50) or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im, 255, 255, 255);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, "Test 測試", $text_color);
imagepng($im, '../img/test.png');
imagedestroy($im);
其實每個函數(shù)的內容都很好理解,函數(shù)名就已經(jīng)寫得很清楚了。當然,我們后面的文章中將詳細地再學習一次。這個最終生成的圖片中,中文也是亂碼的,不過它已經(jīng)是可以當做一個圖片驗證碼來使用了,是不是非常地簡單?
總結
今天的內容不多,也都是比較基礎淺顯的一些函數(shù)的使用。當然,這只是開頭的第一篇文章,GD 庫不是一個簡單的小擴展,它里面的內容非常多,能夠實現(xiàn)的功能也非常復雜,不要走開,持續(xù)關注哦!
測試代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202012/source/1.一起學習PHP中GD庫的使用(一).php
參考文檔: