圖形處理
PHP 的圖形處理,主要功能集中在 PHP 的圖形處理函數。
需要先掌握一些要點。什麼叫圖片,怎麼顯示圖片。
所謂的圖片,其實也是一種檔案,只是內容不是我們肉眼直接可見的。如果我們用記事本開啟一張圖片,只會看到一片亂碼。其實這些亂碼,只是相對我來說是亂碼。對於可以讀寫它的程式來說,一點都不亂。如果我們知道一種圖片的格式,我們就可以自己產生一張圖片。就像我們最早的時候,製作的記事本留言本一樣。
把一些特殊格式的資料,儲存到一個檔案,就可以產生一張圖片。反之,我們如果用 PHP 直接輸出這些內容,瀏覽器也會認為這是一張圖片。
我們先來證實一下這一點,同學們先準備好一張圖片。建議小一點的, JPG 格式就可以了。然後我們使用 PHP 讀取這張圖片,就像普通檔案一樣讀取。
$file = "1.jpg";
$fp = fopen($file, "rb");
$data = fread( $fp, filesize($file));
fclose($fp);
echo $data;
?>
相信對於同學們來說,這個代碼沒有什麼問題吧。
開啟檔案,讀取內容(所有位元組),關閉檔案,輸出內容。
有沒有同學試一下,這個代碼運行後會輸出什麼,截個圖上來看一下。
也許有同學會奇怪吧,怎麼是亂碼。
因為瀏覽器預設,認為我們的 PHP 輸出是文本。即使是亂碼,我們需要告訴瀏覽器,這是一張圖片。這個需要用 header 函數,發送頭資訊,告訴瀏覽器,當前輸出的內容,是格片格式。
Header("Content-type: image/jpeg");
這是 JPG 格式圖片使用的頭資訊,內容類型:圖片/jpeg,需要加在 echo 之前。
$file = "1.jpg";
$fp = fopen($file, "rb");
$data = fread( $fp, filesize($file));
fclose($fp);
Header("Content-type: image/jpeg");
echo $data;
?>
同學們再試一下。
這個代碼證明了一點:即使輸出的是亂碼,只要瀏覽器知道它是什麼內容;它就能正確顯示。
相對的,如果我們把讀出來的內容,儲存到另一個檔案,就可以複製這張圖片。
在這裡,可能會有一些同學會有一些誤解。認為,這裡還是一個網頁。各位同學可以試一下,在開啟的網頁空白處,點一下滑鼠右鍵,查看源檔案,會發現,沒有這個選項。即使有,也是灰的。這是因為,這個不是一個頁面,瀏覽器已經認為,我們這個 PHP 程式,是一張圖片了。
平時我們使用 PHP 進行任何形式的輸出時,瀏覽器認為這是一個 HTML 網頁,才能看到原始碼。
如果我們輸出的是圖片內容,要能正確顯示,就必須告訴瀏覽器,本次輸出,別把我當成網頁,而是當成圖片。也就是說,我們的 php 程式,是一張圖片。如果要想在別的網頁使用這張圖片,需要像平時一樣
把這個 PHP 程式,當成一張圖片來對待,而不能直接在這個程式寫上。
" />
這樣是不對的,這樣只會導致一個結果。
這是不可能顯示得出來的。
所以,使用 PHP 處理圖片的程式,一定是單項功能的 PHP 程式。除非你不輸出這張圖片,而只是把它儲存起來。
$file = "1.jpg";
$fp = fopen($file, "rb");
$data = fread( $fp, filesize($file));
fclose($fp);
$fp = fopen("2.jpg", "wb");
fwrite($fp, $data);
fclose($fp);
?>
如果代碼是這麼寫,就是另一回事,沒有錯。把圖片儲存到另一個地方,然後輸出 HTML 調用這張圖片。要直接輸出圖片的 PHP 程式,一定不可能含有別的輸出,沒有用。只能單純的輸出圖片的內容,就是那堆亂碼。
好了,讀取圖片,輸出圖片都沒有問題了。
檔案的內容是特殊格式,我們看都看不懂,怎麼處理它呢?
PHP 提供了專門的圖形處理函數。
圖形處理函數庫,有一個專用的名字,叫 GD庫。
這個函數庫並不是 PHP 內建的。需要在安裝 PHP 的時候,在 php.ini 裡設定載入。
庫檔案名稱叫 php_gd2.dll。PHP 的安裝包裡就有,在 ext 目錄下。如果哪位同學的 php.ini 裡還沒載入 GD庫,請現在開啟它。
這樣,PHP 才有圖形處理函數可用。
當前 PHP 內建的 GD 庫版本是 2.0.28。PHP 4 帶的是 gd 2.0,PHP 3 時代是 gd 1.6。
為什麼要提這個呢?
因為 gd 2.0 的時候,因為 GIF 圖片的著作權問題。PHP 做為免費開源的語言,無法向 GIF 的著作權商提供著作權費,所以只能暫停對 GIF 圖片的支援。PHP 5 以後,GIF 著作權到期, 我們的 PHP 才重新支援 gif 圖片。
好了,我們開啟 PHP 手冊,看一下 Image 映像函數。
函數很多,但是,大致上可以分成四類:建立,繪畫,設定,輸出。
如果要建立一張圖片,可以使用 imagecreate 函數。從函數名就可以看得出來了,建立映像。從手冊上,可以看得到文法格式。
返回映像資源 imagecreate(寬度 , 高度)
寬度和高度以像素為單位。
還有另一個函數,imagecreatetruecolor 建立一個真彩色映像,支援更多顏色。
建立類的函數,都會返回一個圖片資源,有點類似於 fopen 函數的返回。資源型的資料,內部含有一個可讀寫指標,,讓我們可以對圖片進行編輯操作。
我們先來試試建立一張圖片,先用 imagecreate 函數好了。
為了能看到這張圖片,我們需要輸出。但是我們的經驗告訴我們,資源型的內容不能直接輸出。
圖片形函數,給我們提供了一些函數,分別是:
imagejpeg 以 JPG 格式輸出
imagegif 以 GIF 格式輸出
imagepng 以 PNG 格式輸出
函數格式是一樣的。
imagejpeg( 映像資源 , [儲存路徑])
如果需要儲存這張圖片,就在第二個參數寫上檔案名稱就可以了。如果只是希望直接輸出,第二個參數不寫就行。
我們現在先直接輸出這張映像。
Header("Content-type: image/JPEG");
$img =imagecreate(100, 100);
imagejpeg($img);
建立一張 100*100 的映像,然後用 JPG 格式輸出它。要記得告訴瀏覽器,這是圖片。
啟動並執行結果是什麼樣的呢?有哪位同學截個圖上來看看。
是的,會輸出一張黑色的圖片。因為我們並沒有在上面畫任何內容,也沒告訴它應該用什麼顏色。
我們先來簡單一點的操作,先在上面塗點顏色。這個需要使用 imagecolorallocate 函數。
函數功能是:為一幅映像分配顏色
函數格式是
imagecolorallocate(映像資源, 紅色,綠色,藍色)
三元色,分別用 0 到 255 的數字表示。0是最暗,255是最亮。如果需要白色,三色都是 255 就可以了,黑色就是三色 0,如果只要紅色,就是 255 0 0。
header("Content-type: image/jpeg");
$img =imagecreate(100, 100);
imagecolorallocate($img, 255,0,0);
imagejpeg($img);
我就填上個純紅好了。同學們可以自己試試,分別給紅綠藍設定一些數值,看看結果如何。這個配色,需要一些知識了。同學們也可以直接在各種畫圖工具裡得到這個顏色。
右下角的 紅綠藍 值就可以直接用。很多軟體都有類似的調色盤,很容易可以得到各種顏色值。
這裡有一點要注意。
imagecolorallocate 函數,只有第一次使用的時候,會給映像填上背景色,重新使用,並不會改變背景色。
header("Content-type: image/jpeg");
$img =imagecreate(100, 100);
imagecolorallocate($img, 255,0,0);
imagecolorallocate($img, 0, 0, 255);
imagejpeg($img);
這個代碼,並不會輸出預期的藍色。但是,並不表示函數沒有用。函數依然有效,只是這個顏色沒有被使用而已。我們可以用這個顏色,做其他用途,比如寫字。
我們來試試,在映像上面寫點字。
PHP 給我們提供的函數裡面,有兩個函數可以用於在映像上寫字,分別是 imagestring 和 imagestringup。
imagestring 是橫向寫字
imagestringup 是縱向寫字
如果用 imagestringup 寫的話,我就們看字就得扭著脖子看了。好吧,先用 imagestring。
imagestring 函數原型
imagestring(映像資源, 字型, 開始X座標,開始Y座標, 要寫的字, 顏色)
PHP 內建的字型只有5種,需要用數字1到5表示。
我們來試一下吧。
header("Content-type: image/jpeg");
$img =imagecreate(100, 100);
imagecolorallocate($img, 255,0,0);
$color = imagecolorallocate($img, 0, 0, 255);
imagestring($img, 4, 0,0, 'abcdef', $color);
imagejpeg($img);
你大爺的,好刺眼,我換白底好一點。
有沒有哪個同學試試寫個中文?結果會讓人很失望。
因為 PHP 內建的字型,弱爆了,跟本無法正常顯示中文。怎麼辦呢?
自訂字型。
image 函數,給我們提供了另一個函數,可以使用自訂字型來寫字。嚴格來說是“畫字”。需要一個帶點陣格式的字型檔,而且要支援中文的,最常見的就是 ttf 類型的字型了。如果做過平面設計的同學,對這個一定不陌生,沒做過的同學,也不要緊。我們可以在我們的系統裡面,挖幾個出來用用。系統內建的字型檔,在 C:\windows\fonts 目錄,我們可以在裡面找一個支援中文的字型。WIN 系統內建的字型,大多數都支援中文,我挑一個微軟雅黑。回到我們的 PHP。
要使用這個字型檔來畫字,需要用 imagettftext 函數。
imagettftext 函數原型
imagettftext (映像資源, 字型大小, 字型方向, 開始X座標, 開始Y坐, 字型顏色, 字型檔, 要寫的字 )
我的娘哦,好多參數。估計各位同學也是第一次用這麼多參數的函數吧。
//建立圖片,並設定白底
$img =imagecreate(100, 100);
imagecolorallocate($img, 255,255,255);
//準備一個顏色,
$color = imagecolorallocate($img, 0, 0, 255);
//準備一個字型檔
$font = "msyhbd.ttf";
//映像資源, 字型大小, 字型方向, 開始X座標, 開始Y坐, 字型顏色, 字型檔, 要寫的字
imagettftext($img, 14, 0, 20, 20, $color, $font, "中文支援");
//JPG格式輸出映像
imagejpeg($img);
這個影像檔,如果路徑不在目前的目錄下,要告訴 PHP 在哪裡。
比如 $font = "./font/msyhbd.ttf";
或者 $font = "C:\\windows\\fonts\\msyhbd.ttf";
必須讓 PHP 找得到這個字型檔
imagettftext($img, 14, 180, 150, 150, $color, $font, "中文支援");
字型方向 180度,結果就成這樣子。另外,中文在這裡必須是 utf8 編碼。這個很容易做到,把 PHP 檔案轉換成 utf8 編碼就可以了。使用 gbk 編碼的同學,可以給字型轉換一下編碼。
$text = iconv("gbk", "utf-8", "中文支援");
只要有足夠的字型,我們可以讓 PHP 輸出任意樣式
$font = "FZKANGFW.TTF";
$text = iconv("gbk", "utf-8", "中文支援");
imagettftext($img, 20, 0, 150, 150, $color, $font, $text);
這個效果,配合預定變數 $_SERVER 可以做到一個效果。
$_SERVER['REMOTE_ADDR']
這個伺服器變數,可以得到來訪者的 IP 位址。網上的各種帶 IP 顯示的圖片,就是這麼做出來的。不就是在圖片上寫幾個字麼。
好了。然後我們來學習一下。在上面畫線條。
畫圖函數很多。
imagedashedline - 畫一虛線
imagedestroy - 銷毀一映像
imageellipse - 畫一個橢圓
imagefill - 地區填充
imagefilledarc - 畫一橢圓弧且填充
imagefilledellipse - 畫一橢圓並填充
imagefilledpolygon - 畫一多邊形並填充
imagefilledrectangle - 畫一矩形並填充
畫線是 imageline,其他畫圖函數,同學們可以自行參考手冊。
看來看去,不外乎原理就是:在映像資源上,用什麼顏色,從哪個座標開始,畫什麼。
imageline函數原型
( 映像資料, 開始X座標, 開始Y座標, 結束X座標, 結束Y座標, 顏色 )
在數學中,我們知道XY座標可以確定平面上的一個點,兩個點可以決定一個線段。
//建立圖片,並設定白底
$img =imagecreate(300, 300);
imagecolorallocate($img, 200,200,200);
//準備一個顏色,
$color = imagecolorallocate($img, 0, 0, 255);
//用這個顏色畫一條線
imageline($img, 0,150, 300,150, $color);
//JPG格式輸出映像
imagejpeg($img);
我的映像是 300*300 的大小。從0,150 就是最左邊,中間位置,到最右邊,中間位置。
如果要畫一張網格的話,你就慢慢算座標,然後重複畫就可以了。
for($i=0; $i < 6; $i++) {
$y = $i*50;
imageline($img, 0,$y, 300,$y, $color);
}
豎線什麼的,就不多說了。
還有其他各種線條,形狀,各位同學可以跟據手冊的說明,自行練習。
很多時候,我們圖片是現成的。我們要做的只是縮小,裁剪大小。
圖片是現成的,我們需要把圖片載入進來,跟據圖片的不同類型,我們需要不同的函數來載入。
imagecreatefromjpeg 建立一張映像,來自JPG檔案
imagecreatefromgif GIF
imagecreatefrompng PNG
imagecreatefromwbmp WBMP
imagecreatefromxbm XBM
圖片是什麼類型,就用什麼函數來載入。這些函數,都屬於建立類函數。之前,我們使用寫字,畫線,都屬於繪畫類函數。這樣區分,就不覺得函數多了。很多函數其實是重複的,只是針對於不同的類型。所有的操作,都是針對於畫布,在畫布上畫什麼。
其實 PHP 並不能縮小一張圖片,那隻是一種思路上的技巧。用的是映像複製函數imagecopymerge。
可以把映像的一部份,複製到另一張映像上面,同類的還有另一個函數imagecopyresampled。都是複製映像的一部份,複製到另一張映像上面。這意味著,這樣的操作,需要兩個映像。一個是原圖,一個是新產生的圖。
原圖,我們可以用 imagefrom 系列函數載入進來。新圖,我們可以自己建立。然後再使用映像複製函數,從原圖複製到新圖。
如果複製的只是其中的一個地區,那就是 裁剪功能。如果複製是整個映像大小,新圖的大小和原圖大小不同,就是改變圖片大小,也就是縮圖,或者放大圖。
$image = "1.jpg";
//讀取圖片大小
list($width, $height) = getimagesize($image);
//載入圖片
$bimg = imagecreatefromjpeg($image);
//建立圖片,大小是原圖的一半
$simg =imagecreatetruecolor($width * 0.5, $height * 0.5);
//在原圖上,把原圖的全部,縮小一半,複製過來
imagecopyresampled($simg, $bimg, 0,0, 0,0, $width*0.5, $height*0.5, $width, $height );
//JPG格式輸出小映像
imagejpeg($simg);
應該有同學發現了,這裡使用的是 imagecreatetruecolor 建立新映像。真彩映像,而不是 imagecreate。同學們可以試一下,用 imagecreate 是什麼結果。
複製映像,我選擇了 imagecopyresampled 函數,複製並調整大小。同類函數還有 imagecopyresized。
imagecopyresized
imagecopyresampled
這兩個函數都是複製並調整大小映像。同學們可以自己測試它們的區別。由於參數太多,我這裡幫你們做一個注釋。
新圖, 原圖,
新圖起點X,新圖起點Y,
原圖起點X,原圖起點Y,
新圖寬度,新圖高度,
原圖寬度,原圖高度
兩個一組,一起看就行了。
//載入圖片
$bimg = imagecreatefromjpeg($image);
//建立圖片,大小是原圖的一半
$simg =imagecreatetruecolor($width * 0.5, $height * 0.5);
//在原圖上,把原圖的全部,縮小一半,複製過來
imagecopyresampled($simg, $bimg, 0,0, $width*0.5, $height*0.5, $width, $height, $width, $height );
這個代碼的意思是
$simg, $bimg, //新圖,原圖
0,0, //從新圖的 0*0 開始畫
$width*0.5, $height*0.5, //從原圖的中心點取樣
$width, $height, //新圖和原圖等大小。
$width, $height //到原圖的最右下角座標結束
由於建立的映像只有原圖的一半,這個代碼,會使得最終圖片只顯示原圖中心點開始。右下角的內容。也就是 1/4 原圖的內容,就是所謂的裁剪。
這些函數的參數太多,不太容易看,計算各個採樣座標,需要更細心。
浮水印圖的原理也是一樣的。載入兩張圖,建立兩個映像對象。然後把浮水印圖,複製到原圖上。面。其實都只是一個思路的技巧而已。
圖形函數就講到這裡。
我先來總結一下這一課的要點。
1、一定要先建立映像,載入建立或自己建立。
2、只能在映像上面繪畫,線條,形狀
3、文字只能用 UTF8 編碼,要顯示中文需要中文字型
4、映像本身不能直接調整,只能在複製的過程中調整。
5、如果要直接輸出映像,這個程式不能輸出其他多餘的東西
6、一個直接輸出映像的程式,要把它看成圖片來調用。
映像函數。分為幾類:
建立類:imagecreate、imagecreatefromjpeg
設定類:imagecolorallocate、getimagesize
繪製類:imagecopyresampled、imageline、imagettftext
輸出類:imagejpeg、imagepng
其中繪製類的函數最多,函數格式也很相似,都是:
在映像的XX座標,繪製XX東西
複製操作的函數,座標往往有8個之多。
原圖起點座標,原圖寬高, 這就四個了;
新圖起點座標,新圖寬高, 這裡又四個;
再加上原圖,新圖。有十來個參數。
所以,一般影像處理的過程,往往調試好一個程式之後,都不願意再回頭重新改了。封裝成自訂函數吧。
比如縮圖函數。
function size_img($img, $width, $height) {
中間你就處理吧。
}
這樣提供一個圖片,指定輸出的大小,就可以產生縮圖了。至少用起來方便多了。
http://www.bkjia.com/PHPjc/754899.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/754899.htmlTechArticle圖形處理 PHP 的圖形處理,主要功能集中在 PHP 的圖形處理函數。 需要先掌握一些要點。什麼叫圖片,怎麼顯示圖片。 所謂的圖片,其實也...