9.GD庫圖像處理

PHP中GD庫的使用

GD簡介

PHP 不僅限于只產(chǎn)生 HTML 的輸出,還可以創(chuàng)建及操作多種不同格式的圖像文件。PHP提供了一些內(nèi)置的圖像信息函數(shù),也可以使用GD函數(shù)庫創(chuàng)建新圖像或處理已有的圖像。目前GD2庫支持GIF、JPEG、PNG和WBMP等格式。此外還支持一些FreeType、Type1等字體庫。

  • JPEG 是一種壓縮標(biāo)準(zhǔn)的名字,通常是用來存儲照片或者存儲具有豐富色彩和色彩層次的圖像。這種格式使用了有損壓縮。

  • PNG 是可移植的網(wǎng)絡(luò)圖像,對圖像采用了無損壓縮標(biāo)準(zhǔn)。

  • GIF 原義是“圖像互換格式”,是一種基于LZW算法的連續(xù)色調(diào)的無損壓縮格式 。

在PHP中創(chuàng)建一個圖像應(yīng)該完成如下所示的4個步驟:
  1. 創(chuàng)建一個背景圖像(也叫畫布),以后的操作都基于此背景圖像。

  2. 在背景上繪制圖像輪廓或輸入文本。

  3. 輸出最終圖形

  4. 釋放資源

<?php       
    //1. 創(chuàng)建畫布 
    $im = imageCreateTrueColor(200, 200);       //建立空白背景
    $white = imageColorAllocate ($im, 255, 255, 255);   //設(shè)置繪圖顏色
    $blue  = imageColorAllocate ($im, 0, 0, 64);
    //2. 開始繪畫
    imageFill($im, 0, 0, $blue);                            //繪制背景
    imageLine($im, 0, 0, 200, 200, $white);         //畫線
    imageString($im, 4, 50, 150, 'Sales', $white);      //添加字串
    //3. 輸出圖像
    header('Content-type: image/png');
    imagePng ($im);     //以 PNG 格式將圖像輸出
    //4. 釋放資源
    imageDestroy($im);  
?>

畫布管理

  • imagecreate -- 新建一個基于調(diào)色板的圖像
resource imagecreate ( int x_size, int y_size )

本函數(shù)用來建立空新畫布,參數(shù)為圖片大小,單位為像素 (pixel)。支持256色。

  • imagecreatetruecolor -- 新建一個真彩色圖像
resource imagecreatetruecolor ( int x_size, int y_size )

新建一個真彩色圖像畫布 ,需要 GD 2.0.1 或更高版本,不能用于 GIF 文件格式。

  • imagedestroy -- 銷毀一圖像
bool imagedestroy ( resource image ) 

imagedestroy() 釋放與 image 關(guān)聯(lián)的內(nèi)存。

設(shè)置顏色

  • imagecolorallocate -- 為一幅圖像分配顏色
語法:int imagecolorallocate ( resource image, int red, int green, int blue )

imagecolorallocate() 返回一個標(biāo)識符,代表了由給定的 RGB 成分組成的顏色。red,green 和 blue 分別是所需要的顏色的紅,綠,藍成分。

這些參數(shù)是 0 到 255 的整數(shù)或者十六進制的 0x00 到 0xFF。

imagecolorallocate() 必須被調(diào)用以創(chuàng)建每一種用在 image 所代表的圖像中的顏色

$im    = imagecreatetruecolor(100, 100); //創(chuàng)建畫布的大小為100x100
$red   = imagecolorallocate($im, 255, 0, 0); //由十進制整數(shù)設(shè)置一個顏色
$white = imagecolorallocate($im, 0xFF, 0xFF, 0xFF); // 十六進制方式
  • imagepolygon -- 畫一個多邊形
語法:bool imagepolygon ( resource image, array points, int num_points, int color )

imagepolygon() 在圖像中創(chuàng)建一個多邊形。points 是一個 PHP 數(shù)組,包含了多邊形的各個頂點坐標(biāo),即 points[0] = x0,points[1] = y0,points[2] = x1,points[3] = y1,以此類推。num_points 是頂點的總數(shù)。

  • imagefilledpolygon -- 畫一多邊形并填充
語法:bool imagefilledpolygon ( resource image, array points, int num_points, int color )

imagefilledpolygon() 在 image 圖像中畫一個填充了的多邊形。points 參數(shù)是一個按順序包含有多邊形各頂點的 x 和 y 坐標(biāo)的數(shù)組。 num_points 參數(shù)是頂點的總數(shù),必須大于 3。

生成圖像

  • imagegif -- 以 GIF 格式將圖像輸出到瀏覽器或文件
語法:bool imagegif (resource image [,string filename] ) 
  • imagejpeg -- 以 JPEG 格式將圖像輸出到瀏覽器或文件
語法:bool imagejpeg (resource image [,string filename [, int quality]] ) 
  • imagepng -- 以 PNG 格式將圖像輸出到瀏覽器或文件
語法:bool imagepng (resource image [,string filename] )
  • imagewbmp -- 以 WBMP 格式將圖像輸出到瀏覽器或文件
語法:bool imagewbmp (resource image [, string filename [, int foreground]] ) 

繪制圖像

  • imagefill -- 區(qū)域填充
語法:bool imagefill(resource image,int x,int y, int color) 

imagefill() 在 image 圖像的坐標(biāo) x,y(圖像左上角為 0, 0)處用 color 顏色執(zhí)行區(qū)域填充(即與 x, y 點顏色相同且相鄰的點都會被填充)。

  • imagesetpixel -- 畫一個單一像素
語法:bool imagesetpixel ( resource image, int x, int y, int color ) 

imagesetpixel() 在 image 圖像中用 color 顏色在 x,y 坐標(biāo)(圖像左上角為 0,0)上畫一個點。

  • imageline -- 畫一條線段
語法:bool imageline ( resource image, int x1, int y1, int x2, int y2, int color ) 

imageline() 用 color 顏色在圖像 image 中從坐標(biāo) x1,y1 到 x2,y2(圖像左上角為 0, 0)畫一條線段。

  • imagerectangle -- 畫一個矩形
語法:bool imagerectangle ( resource image, int x1, int y1, int x2, int y2, int col )

imagerectangle() 用 col 顏色在 image 圖像中畫一個矩形,其左上角坐標(biāo)為 x1, y1,右下角坐標(biāo)為 x2, y2。圖像的左上角坐標(biāo)為 0, 0。

  • imagefilledrectangle -- 畫一矩形并填充
語法:bool imagefilledrectangle ( resource image, int x1, int y1, int x2, int y2, int color )

imagefilledrectangle() 在 image 圖像中畫一個用 color 顏色填充了的矩形,其左上角坐標(biāo)為 x1,y1,右下角坐標(biāo)為 x2,y2。0, 0 是圖像的最左上角。

  • imageellipse -- 畫一個橢圓
語法:bool imageellipse ( resource image, int cx, int cy, int w, int h, int color )

imageellipse() 在 image 所代表的圖像中畫一個中心為 cx,cy(圖像左上角為 0, 0)的橢圓。w 和 h 分別指定了橢圓的寬度和高度,橢圓的顏色由 color 指定。

  • imagefilledellipse -- 畫一橢圓并填充
語法:bool imagefilledellipse ( resource image, int cx, int cy, int w, int h, int color )

imagefilledellipse() 在 image 所代表的圖像中以 cx,cy(圖像左上角為 0, 0)為中心畫一個橢圓。w 和 h 分別指定了橢圓的寬和高。橢圓用 color 顏色填充。如果成功則返回 TRUE,失敗則返回 FALSE。

  • imagearc -- 畫橢圓弧
bool imagearc ( resource image, int cx, int cy, int w, int h, int s, int e, int color )

imagearc() 以 cx,cy(圖像左上角為 0, 0)為中心在 image 所代表的圖像中畫一個橢圓弧。w 和 h 分別指定了橢圓的寬度和高度,起始和結(jié)束點以 s 和 e 參數(shù)以角度指定。0°位于三點鐘位置,以順時針方向繪畫。

  • imagefilledarc -- 畫一橢圓弧且填充
bool imagefilledarc ( resource image, int cx, int cy, int w, int h, int s, int e, int color, int style )

imagefilledarc() 在 image 所代表的圖像中以 cx,cy(圖像左上角為 0, 0)畫一橢圓弧。如果成功則返回 TRUE,失敗則返回 FALSE。w 和 h 分別指定了橢圓的寬和高,s 和 e 參數(shù)以角度指定了起始和結(jié)束點。style 可以是下列值按位或(OR)后的值:
IMG_ARC_PIE IMG_ARC_CHORD
IMG_ARC_NOFILL IMG_ARC_EDGED
IMG_ARC_PIE 和 IMG_ARC_CHORD 是互斥的;IMG_ARC_CHORD 只是用直線連接了起始和結(jié)束點,IMG_ARC_PIE 則產(chǎn)生圓形邊界。IMG_ARC_NOFILL 指明弧或弦只有輪廓,不填充。IMG_ARC_EDGED 指明用直線將起始和結(jié)束點與中心點相連,和 IMG_ARC_NOFILL 一起使用是畫餅狀圖輪廓的好方法(而不用填充)。

在圖像中繪制文字

  • imagestring -- 水平地畫一行字符串
語法:bool imagestring ( resource image, int font, int x, int y, string s, int col )

imagestring() 用 col 顏色將字符串 s 畫到 image 所代表的圖像的 x,y 坐標(biāo)處(這是字符串左上角坐標(biāo),整幅圖像的左上角為 0,0)。如果 font 是 1,2,3,4 或 5,則使用內(nèi)置字體。

  • imagestringup -- 垂直地畫一行字符串
語法:bool imagestringup ( resource image, int font, int x, int y, string s, int col )
  • imagechar -- 水平地畫一個字符
語法:bool imagechar ( resource image, int font, int x, int y, string c, int color )

imagechar() 將字符串 c 的第一個字符畫在 image 指定的圖像中,其左上角位于 x,y(圖像左上角為 0, 0),顏色為 color。如果 font 是 1,2,3,4 或 5,則使用內(nèi)置的字體(更大的數(shù)字對應(yīng)于更大的字體)。

  • imagecharup -- 垂直地畫一個字符
語法:bool imagecharup ( resource image, int font, int x, int y, string c, int color )

imagecharup() 將字符 c 垂直地畫在 image 指定的圖像上,位于 x,y(圖像左上角為 0, 0),顏色為 color。如果 font 為 1,2,3,4 或 5,則使用內(nèi)置的字體。

  • imagettftext -- 用 TrueType 字體向圖像寫入文本
語法 :array imagettftext ( resource image, float size, float angle, int x, int y, int color, string fontfile, string text ) 
  • imagestring()用 col 顏色將字符串 s 垂直地畫到 image 所代表的圖像的 x, y 座標(biāo)處(圖像的左上角為 0, 0)。如果 font 是 1,2,3,4 或 5,則使用內(nèi)置字體。

驗證碼的繪制和使用

驗證碼(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自動區(qū)分計算機和人類的圖靈測試)的縮寫,是一種區(qū)分用戶是計算機和人的公共全自動程序。

使用驗證碼的目的:可以防止:惡意破解密碼、刷票、論壇灌水,有效防止某個黑客對某一個特定注冊用戶用特定程序暴力破解方式進行不斷的登陸嘗試。
驗證碼是現(xiàn)在很多網(wǎng)站通行的方式(比如招商銀行的網(wǎng)上個人銀行,百度社區(qū))。
驗證碼的樣式也是千奇百態(tài),本節(jié)重點講解使用GD庫繪制圖像的方式。

設(shè)計驗證碼的步驟

gd庫支持

  1. 生成底圖
    產(chǎn)生一塊圖片
    創(chuàng)建畫布
    $img=imagecreatetruecolor('x','y')
    準(zhǔn)備顏色
    $bgcolor=imagecolorallocate($img,255,255,255)
    填充顏色
    imagefill($image,'x','y',$bgcolor)

  2. 在圖片中生成干擾元素
    在底圖上顯示隨機數(shù)字
    準(zhǔn)備字體顏色
    可隨機
    $fontcolor=imagecolorallocate($img,0,0,0);
    準(zhǔn)備字體大小
    $fontsize=10
    準(zhǔn)備字體內(nèi)容
    $content = rand(0,9)
    將內(nèi)容填充到畫布上
    imagestring($img,$fontsize,$x,$y,$content,$fontcolor)
    注意:控制好字體大小與分布,避免字體重疊或顯示不全
    為驗證碼增加干擾元素,干擾的點或線
    準(zhǔn)備點的顏色
    可隨機
    $pointcolor=imagecolorallocate($img,175,175,175)
    畫點
    imagesetpixel($img,$x,$y,$pointcolor)
    增加線干擾元素
    準(zhǔn)備顏色
    可隨機
    $linecolor=imagecolorallocate($img,90,90,90)
    畫線
    imageline($img,x,y,x,y,$linecolor)
    注意:干擾元素一定要控制好顏色,避免喧賓奪主

  3. 生成驗證內(nèi)容
    生成無規(guī)律內(nèi)容
    數(shù)字、字母、數(shù)字加字母
    服務(wù)器保存改內(nèi)容

  4. 生成驗證碼圖片
    輸出
    header('content-type:image/png')
    imagepng($rimg)
    銷毀資源
    imagedestroy($img)

  5. 校驗驗證內(nèi)容
    在服務(wù)器記錄驗證碼信息,便于用戶輸入后做校驗
    session_start()
    必須處于腳本最頂部
    多服務(wù)器情況,需要考慮集中管理session信息
    用戶輸入對比服務(wù)器保存內(nèi)容

PHP圖片處理(縮放、裁剪、水印、旋轉(zhuǎn)和翻轉(zhuǎn))

圖片背景管理

從指定的圖片文件或 URL地址來新建一個圖像。成功則返回一個圖像標(biāo)識符,失敗時返回一個空字符串,并且輸出一條錯誤信息。

由于格式不同,則需要分別使用對應(yīng)圖片背景處理函數(shù)。

  • 從 PNG 文件或 URL 新建一圖像
resource imagecreatefrompng ( string filename )
  • 從 JPEG 文件或 URL 新建一圖像
resource imagecreatefromjpeg ( string filename ) 
  • 從 GIF 文件或 URL 新建一圖像
resource imagecreatefromgif ( string filename )
  • 從 WBMP 文件或 URL 新建一圖像
resource imagecreatefromwbmp ( string filename )

其他圖像處理函數(shù):

  • 取得圖像寬度
int imagesx ( resource image )
  • 取得圖像高度
int imagesy ( resource image ) 
  • 取得圖像大小、類型等信息
array getimagesize ( string $filename [, array &$imageinfo ] )

圖片縮放和裁剪

bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )

重采樣拷貝部分圖像并調(diào)整大小,是將一幅圖像中的一塊正方形區(qū)域拷貝到另一個圖像中,平滑地插入像素值,因此,尤其是,減小了圖像的大小而仍然保持了極大的清晰度。成功時返回 TRUE, 或者在失敗時返回 FALSE。其中dst_image 和 src_image 分別是目標(biāo)圖像和源圖像的標(biāo)識符。

添加圖片水印

bool imagecopy ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h )

拷貝圖像的一部分(也就是圖片合成)。
將 src_im 圖像中坐標(biāo)從 src_x,src_y 開始,寬度為 src_w,高度為 src_h 的一部分拷貝到 dst_im 圖像中坐標(biāo)為 dst_x 和 dst_y 的位置上。

圖片旋轉(zhuǎn)和翻轉(zhuǎn)

resource imagerotate ( resource $src_im , float $angle , int $bgd_color [, int $ignore_transparent ] )

用給定角度旋轉(zhuǎn)圖像
將 src_im 圖像用給定的 angle 角度旋轉(zhuǎn)。bgd_color 指定了旋轉(zhuǎn)后沒有覆蓋到的部分的顏色。
旋轉(zhuǎn)的中心是圖像的中心,旋轉(zhuǎn)后的圖像會按比例縮小以適合目標(biāo)圖像的大小——邊緣不會被剪去。
如果 ignore_transparent 被設(shè)為非零值,則透明色會被忽略(否則會被保留)。

Have a try

  1. 使用GD庫實現(xiàn)驗證碼?
  2. 實現(xiàn)在一張圖片上添加文字水印。
  3. 實現(xiàn)一張圖片的等比縮小一半的處理(如a.jpg圖片會生成一個s_a.jpg的小圖);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容