PHP7語言基礎——圖形圖像處理


PHP能做很多事情,用於web開發只是冰山一角,如果你願意或者你對PHP足夠了解,你甚至可以用PHP來開發一條PS系統,是的,沒錯,PHP可以創建和處理包括GIF、PNG、JPEG、WBMP以及XPM在內的多種格式的圖像。比PS等軟件更加方便的是,PHP可以直接將圖像數據流輸出到瀏覽器。

前提條件

要在PHP中使用圖像處理功能,需要加載GD庫,或者安裝其他的第三方圖形庫。

在PHP中加載GD庫

一下內容引用自官方手冊:

要激活 GD 支持,配置 PHP 時加上 –with-gd[=DIR] ,DIR 是 GD 的基本安裝目錄。要使用推薦的綁定的 GD 庫版本(首次綁定於 PHP 4.3.0),使用 –with-gd 。要編譯 GD 庫,需要libpng 和 libjpeg。

在 Windows 中,需要將 GD2 的 DLL 文件 php_gd2.dll 作爲一個擴展包含在 php.ini 中。GD1 的 DLL 文件 php_gd.dll 在 PHP 4.3.2 中被刪除了。此外要注意首選的真彩色圖像函數,例如imagecreatetruecolor(),需要 GD2。

自PHP5.0開始,就自帶GD庫了。

啓用GD庫,只需要將php.ini中extension=php_gd2.dll前面的“;”去掉即可。

GD的圖像處理函數

函數 功能
gd_info 獲得當前安裝的GD庫的信息,返回一個關聯數組描述了安裝的 GD 庫的版本和性能。
getimagesize 取得圖像大小
getimagesizefromstring 從字符串中獲取圖像尺寸信息
image_type_to_extension 取得圖像類型的文件後綴
image_type_to_mime_type 取得getimagesize、exif_read_data、exif_thumbnail、exif_imagetype所返回的圖像類型的MIME類型
image2wbmp 以WBMP格式將圖像輸出到瀏覽器或文件
imageaffine 返回經過仿射變換後的圖像,剪切區域可選
imageaffinematrixconcat 連接兩個仿射變換矩陣
imageaffinematrixget 得到一個仿射變換矩陣
imagealphablending 設定圖像的混色模式
imageantialias 是否使用antialias(抗鋸齒)功能
imageearc 畫橢圓弧
imagechar 水平地畫一個字符
imagecharup 垂直地畫一個字符
imagecolorallocate 爲一幅圖像分配顏色
imagecolorallocatealpha 爲一幅圖像分配顏色+alpha
imagecolorat 取得某像素的顏色索引值
imagecolorclosest 取得指定的顏色最進階的顏色索引值
imageclolorclosetalpha 取得與指定的顏色加透明度最接近的顏色
imagecolorclosesthwb 取得與給定顏色最僅僅的色度的黑白色的索引
imagecolordeallocate 取消圖像顏色的分配
imagecolorexact 取得指定顏色的索引值
imagecolorexactalpha 取得指定的顏色加透明度的索引值
imagecolormatch 是一個圖像中調色板版本的顏色與真彩色版本更能匹配
imagecolorresolve 取得指定顏色的索引值或有可能得到的最接近的替代值
imagecolorresolvealpha 取得指定顏色 + alpha 的索引值或有可能得到的最接近的替代值
imagecolorset 給指定調色板索引設定顏色
imagecolorsforindex 取得某索引的顏色
imagecolorstotal 取得一幅圖像的調色板中顏色的數目
imagecolortransparent 將某個顏色定義爲透明色
imageconvolution 用係數 div 和 offset 申請一個 3x3 的卷積矩陣
imagecopy 複製圖像的一部分
imagecopymerge 複製併合並圖像的一部分
imagecopymergegray 用灰度拷貝併合並圖像的一部分
imagecopyresampled 重採樣複製部分圖像並調整大小
imagecopyresized 複製部分圖像並調整大小
imagecreate 新建一個基於調色板的圖像
imagecreatefrombmp 由BMP文件或 URL 創建一個新圖象。
imagecreatefromgd2 從GD2文件或URL新建一個圖像
imagecreatefromgd2part 從給定的GD2文件或URL中的部分新建一個圖像
imagecreatefromgd 從GD文件或URL新建一個圖像
imagecreatefromgif 從gif文件或URL新建一個圖像
imagecreatefromjpeg 從JPEG文件或URL新建一個圖像
imagecreatefrompng 從PNG文件或URL新建一個圖像
imagecreatefromstring 從字符串中的圖像流新建一圖像
imagecreatefromwbmp 從WBMP文件或URL新建一個圖像
imagecreatefromxbm 從XBM文件或URL新建一個圖像
imagecreatefromxpm 從XPM文件或URL新建一個圖像
imagecreatetruecolor 新建一個真彩色圖像
imagecrop 剪裁圖像到給定的矩形
imagecropauto 使用一種模式自動剪裁圖像到給定矩形
iamgedashedline 畫一虛線
imagedestroy 銷燬一圖像
imageellipse 畫一個橢圓
imagefill 區域填充
imagefilledarp 畫一橢圓弧且填充
imagefilledellipse 畫一橢圓並填充
imagefilledpolygon 畫一多邊形並填充
imagefilledrectangle 畫一矩形並填充
imagefilltoborder 區域填充到指定顏色的邊界爲止
imagefilter 對圖像使用過濾器
imageflip 使用給定模式翻轉圖像
imagefontheight 取得字體高度
imagefontwidth 得字體寬度
imageftbbox 給出一個使用 FreeType 2 字體的文本框
imagefttext 使用 FreeType 2 字體將文本寫入圖像
imagegammacorrect 對 GD 圖像應用 gamma 修正
imagegd 將 GD 圖像輸出到瀏覽器或文件
imagegd2 將 GD2 圖像輸出到瀏覽器或文件
imagegetclip 得到剪裁矩形
imagegif 以GIF格式將圖像輸出到瀏覽器或文件
imagegrabscreen 捕獲整個屏幕
imagegrabwindow 捕獲一個窗口
imageinterlace 激活或禁止隔行掃描
imageistruecolor 檢查圖像是否爲真彩色圖像
imagejpeg 以JPEG格式將圖像輸出到瀏覽器或文件
imagelayereffect 設定alpha混色標誌以使用綁定的libgd分層效果
imageline 畫一條直線
imageloadfont 載入一個新字體
imagepalettecopy 將調色板從一幅圖像拷貝到另一幅
imagepalettetotruecolor 將基於調色板的文件轉換爲真彩色
imageopenpolygon 畫一個開放多邊形
imagepng 以PNGF格式將圖像輸出到瀏覽器或文件
imagepolygon 畫一個多邊形
imagerectangle 畫一個矩形
imagerotate 用給定角度旋轉圖像
imagesetstyle 設定畫線的風格
imagesetthickness 設定畫線的寬度
imagesx 取得圖像寬度
imagesy 取得圖像高度
imagetruecolortopalette 將真彩色圖像轉換爲調色板圖像
imagettfbbox 取得使用 TrueType 字體的文本的範圍
imagettftext 用 TrueType 字體向圖像寫入文本

圖像信息

獲取圖像信息

  1. getimagesize()
    函數定義:

    getimagesize(string $filename[, array &$imageinfo]):array
    

    該函數將測定任何JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 圖像文件的大小並返回圖像的尺寸以及文件類型和一個可以用於普通HTML 文件中 IMG 標記中的 height/width 文本字符串。如果filename指定的圖像不能訪問或者不是一個有效的圖像文件,該函數將返回FALSE併產生一條E_WARNING級別的錯誤。

    參數:

    • filename:待測定的圖像文件路徑。
    • imageinfo:可選參數imageinfo允許從圖像文件中提取一些擴展信息。它將以關聯數組返回不同的JPG文件的APP標識。一些程序用這些APP標識來在圖像中嵌入文本信息。一個非常常見的是在APP13標識中嵌入IPTC信息。可以用iptcparse()函數來將二進制的APP13標識解析爲可讀的信息。

    返回值:

    該函數返回一個具有四個元素的數組。索引 0 包含圖像寬度的像素值,索引 1 包含圖像高度的像素值。索引 2 是圖像類型的標記:1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM。這些標記與 PHP 4.3.0 新加的 IMAGETYPE 常量對應。索引 3 是文本字符串,內容爲"height=“yyy” width=“xxx”",可直接用於 IMG 標記。

    該函數還會返回額外的參數mime,符合該圖像的MIME類型。此信息可以用來在HTTP Content-type頭信息中發送正確的信息。對於JPG圖像,還會多返回兩個索引:channels和bits。對於RGB圖像,channels值爲3;對於CMYK圖像,channels值爲4。bits是每種顏色的位數。

    【示例】

    <?php
    echo "<pre>";
    // 查看gd庫信息
    print_r(gd_info());
    
    $imageinfo = array();
    
    // 獲取圖像信息
    print_r(getimagesize('1.jpg', $imageinfo));
    echo "<br />";
    var_dump($imageinfo);
    echo "</pre>";
    

    程序輸出結果: 在這裏插入圖片描述

    通過以上打印結果可知,該圖像的寬度爲650,高度爲344,索引值爲2的值爲2說明圖像是jpg圖像,除此之外,還獲得了圖像的channels、bits以及mime類型。

  2. getimagesizeformstring()
    該函數與getimagesize()函數相同。不同之處在於該函數第一個參數是圖像數據的字符串表達,而不是文件名。該函數定義如下:

    getimagesizefromstring(string $imagedata[, array &$imageinfo]):array
    

    參數:

    • imagedata:圖像數據的字符串表示。
    • imageinfo:與getimagesize()函數的imageinfo參數相同。

    返回值:

    getimagesize()函數返回值相同。

    【示例】

    <?php
    // 以文件名方式打開
    $img = '1.jpg';
    $img_info1 = getimagesize($img);
    
    // 以字符串格式打開
    // 首先將圖片讀入到流中
    $img_data = file_get_contents($img);
    $img_info2 = getimagesizefromstring($img_data);
    
    // 輸出圖片信息
    echo "<pre>";
    print_r($img_info1);
    print_r($img_info2);
    echo "</pre>";
    

    程序輸出結果:

    在這裏插入圖片描述

    從輸出可以看到,兩個函數返回的結果是一致的,只是使用函數時圖像文件的打開方式不同。

  3. imagesx()imagesy()
    這兩個函數分別獲取圖像的寬度和高度,先來看一下函數定義:

    imagesx(resource $img):int
    imagesy(resource $img):int
    

    這兩個函數都接收一個img資源作爲參數,分別返回所代表的圖像的寬度和高度。

    這兩個函數沒什麼可說,使用起來也很簡單,沒什麼可說的。

    【示例】

    <?php
    // 創建一個resource
    $img = imagecreatetruecolor(300, 200);
    echo imagesx($img) . "<br />";
    echo imagesy($img) . "<br />";
    

    以上代碼會分別輸出300和200。

圖像繪製

PHP中的GD庫可用於創建和處理圖片,一般通過以下4個步驟對圖像進行操作。

  1. 創建畫布
  2. 在畫布上繪製圖形
  3. 保存並輸出結果圖像
  4. 銷燬圖像資源

創建畫布

使用imagecreate()函數可以創建一個基於調色板的圖像。語法如下:

imagecreate(int $x_size, int $y_size):resource

該函數返回一個圖像資源,代表了一幅大小爲x_sizey_size的空白圖像。

【示例】

<?php
// 設置mime類型
header("Content-type: image/png");

// 第一步:創建畫布
$im = @imagecreate(100, 50) or die("無法初始化新的GD圖像流");
// 第二步:在畫布上創建圖像
// 設置背景色
$background_color = imagecolorallocate($im, 255, 255, 255);
// 設置文字顏色
$text_color = imagecolorallocate($im, 233, 14, 91);
// 在畫布上畫一個字符串
imagestring($im, 1, 5, 5, "A Simple Text String", $text_color);
// 第三步:保存並輸出圖像
imagepng($im);
// 第四步:銷燬圖像資源
imagedestroy($im);

程序輸出結果:

在這裏插入圖片描述

也可以使用imagecreatetruecolor()創建畫布資源。並且系統推薦使用此函數。其函數定義如下:

imagecreatetruecolor(int $width, int $height):resource

該函數創建一個基於真彩色的圖像。也返回一個圖像資源,代表了一幅大小爲widthheight的黑色圖像。

【示例】

<?php
// 設置mime類型
header("Content-type: image/png");

// 第一步:創建畫布
$im = @imagecreatetruecolor(100, 50) or die("無法初始化新的GD圖像流");
// 第二步:在畫布上創建圖像
// 設置文字顏色
$text_color = imagecolorallocate($im, 233, 14, 91);
// 在畫布上畫一個字符串
imagestring($im, 1, 5, 5, "A Simple Text String", $text_color);
// 第三步:保存並輸出圖像
imagepng($im);
// 第四步:銷燬圖像資源
imagedestroy($im);

程序輸出結果:

在這裏插入圖片描述

注意:以上函數中在圖像中輸出的字符串爲英文,如果是中文字符串將顯示亂碼,要輸出中文最好使用imagettftext()函數。

定義顏色

既然要處理圖像,自然少不了和顏色打交道,在PHP中可以使用imagecolorallocate()函數來指定顏色,其函數定義如下:

imagecolorallocate(resource $image, int $red, int $green, int $blue):int

該函數返回一個標識符,代表了由給定的RGB成分組成的顏色。redgreenblue分別是所需要的顏色的紅、綠、藍成分。這些參數是0到255的整數或者十六進制的0x00到0xFF。

PHP中還有一個imagecolorallocatealpha()函數,可以給圖像分配顏色,同時還能指定透明度。其函數定義如下:

imagecolorallocatealpha(resource $image, int $red, int $green, int $blue, int $alpha):int

該函數的行爲同imagecolorallocate()相同,只是多了一個額外的透明度參數alpha,其值從0到127。0表示完全不透明,127表示完全透明。

以上兩個函數在顏色分配失敗時都返回FALSE。

【示例】

<?php
// 不要忘記設置mime類型,否則無法輸出圖像
header("Content-type: image/png");

// 第一步:創建畫布
$size = 300;
// 創建一個300×300的畫布
$im = imagecreatetruecolor($size, $size);
// 第二步:在畫布上創建圖像
// 用白色背景加黑色邊框畫個方框
// 設置白色背景
$back = imagecolorallocate($im, 255,255,255);
// 設置黑色邊框
$border = imagecolorallocate($im, 0, 0, 0);
// 用白色背景填充一個矩形
imagefilledrectangle($im, 0, 0, $size - 1, $size - 1, $back);
// 畫一個矩形不填充顏色,設置邊框顏色爲黑色
imagerectangle($im, 0, 0, $size-1, $size - 1, $border);
// 在矩形中繪製三個圓
// 指定圓的座標
$yellow_x = 100;
$yellow_y = 75;
$red_x = 120;
$red_y = 165;
$blue_x = 187;
$blue_y = 125;
// 設置圓的半徑
$radius = 150;

// 用alpha值分配一些顏色
$yellow = imagecolorallocatealpha($im, 255, 255, 0, 75);
$red = imagecolorallocatealpha($im, 255, 0, 0, 75);
$blue = imagecolorallocatealpha($im, 0, 0, 255, 75);

// 在矩形中畫出三個交迭的圓
imagefilledellipse($im, $yellow_x, $yellow_y, $radius, $radius, $yellow);
imagefilledellipse($im, $red_x, $red_y, $radius, $radius, $red);
imagefilledellipse($im, $blue_x, $blue_y, $radius, $radius, $blue);

// 第三步:保存並輸出圖像
imagepng($im);

// 第四步:銷燬圖像資源
imagedestroy($im);

程序輸出結果:

在這裏插入圖片描述

繪製圖形

PHP的GD庫提供了許多繪製圖像的函數,可以像畫圖工具一樣,繪製一些簡單的形狀圖形。

  1. 繪製橢圓
    使用imageellipse()函數可以繪製一個橢圓,其函數定義如下:

    imageellipse(resource $image, int $cx, int $cy, int $width, int $height, int $color):bool
    

    該函數在指定座標上畫一個橢圓。成功時返回TRUE,否則返回FALSE。

    參數:

    • image:由圖像創建函數返回的圖像資源。
    • cx:圓心的X座標。
    • cy:圓心的Y座標。
    • width:橢圓的寬度。
    • height:橢圓的高度。
    • color:橢圓的顏色。

    【示例】

    <?php
    // 新建一個畫布
    $im = imagecreatetruecolor(400, 300);
    // 填充背景色
    $bg = imagecolorallocate($im, 0, 0, 0);
    // 選擇橢圓的顏色
    $color_ellipse = imagecolorallocate($im, 255, 255, 255);
    // 在畫布上畫出橢圓
    imageellipse($im, 200, 150, 300, 200, $color_ellipse);
    // 輸出圖像
    header("Content-type: image/png");
    imagepng($im);
    // 關閉圖像資源
    imagedestroy($im);
    

    程序輸出結果:

    在這裏插入圖片描述

    還有一個函數imagefilledellipse()也是繪製一個橢圓,區別是它會爲橢圓填充指定的color顏色。

  2. 繪製多邊形
    PHP中使用imagepolygon()imagefilledpolygon()函數繪製多邊形,函數定義如下:

    imagepolygon(resource $image, array $points, int $num_points, int $color):bool
    imagefilledpolygon(resource $image, array $points, int $numn_points, int $color):bool
    

    以上兩個函數都是用來創建多邊形的。參數points是一個PHP數組,包含了多邊形的各個頂點座標,參數num_points是頂點的總數。兩個函數的區別在於一個用color作爲邊框顏色,一個用color作爲填充顏色。

    【示例】

    <?php
    // 新建一個畫布
    $im = imagecreatetruecolor(800, 600);
    // 填充背景色
    $bg = imagecolorallocate($im, 0, 0, 0);
    // 爲多邊形設置邊框或填充的顏色
    $color_polygon = imagecolorallocate($im, 255, 255, 255);
    // 在畫布上畫出無填充的多邊形
    imagepolygon($im,
                 array(
                     0, 0,
                     100, 200,
                     300, 200
                 ),
                 3,
                 $color_polygon);
    // 在畫布上畫出填充的多邊形
    imagefilledpolygon($im,
                        array(
                            300, 400,
                            200, 600,
                            500, 500
                        ),
                        3,
                        $color_polygon);
    // 輸出圖像
    header("Content-type: image/png");
    imagepng($im);
    // 關閉圖像資源
    imagedestroy($im);
    

    程序輸出結果:

    在這裏插入圖片描述

  3. 繪製矩形
    在PHP中使用imagerectangle()imagefilledrectangle()函數來繪製矩形,函數語法格式如下:

    imagerectangle(resource $image, int $x1, int $y1, int $x2, int $y2, int $color):bool
    imagefilledrectangle(resource $image, int $x1, int $y1, int $x2, int $y2, int $color):bool
    

    以上兩個函數用col顏色在image圖像資源中畫一個矩形,其左上角座標爲x1, y1, 右下角座標爲x2, y2.圖像的左上角座標爲0,0。

    【示例】

    <?php
    // 新建一個畫布
    $im = imagecreatetruecolor(250, 250);
    // 填充背景色
    $bg = imagecolorallocate($im, 10, 110, 25);
    // 設置矩形填充色
    $color_rectangle = imagecolorallocate($im, 0, 0, 255);
    // 在畫布上畫出填充矩形
    imagefilledrectangle($im, 100, 200, 50, 50, $color_rectangle);
    // 輸出圖像
    header("Content-type: image/png");
    imagepng($im);
    // 關閉圖像資源
    imagedestroy($im);
    

    程序輸出結果:

    在這裏插入圖片描述

  4. 繪製橢圓弧
    在PHP中使用imagearc()imagefilledarc()繪製橢圓弧,其函數定義如下:

    imagearc(resource $image, int $cx, int $cy, int $w, int $h, int $s, int $e, int $color):bool
    imagefilledarc(resource $image, int $cx, int, $cy, int $w, int $h, int $s, int $e, int color, int $style):bool
    

    以上兩個函數以cxcy(圖像左上角爲0,0)爲中心在image所代表的圖像中畫一個橢圓弧。wh分別制定了橢圓的寬度和高度,起始和結束點以se參數爲角度指定。0°位於三點鐘位置,以順時針方向繪製。

    【示例】

    <?php
    // 新建一個畫布
    $im = imagecreatetruecolor(200, 200);
    // 填充背景色
    $bg = imagecolorallocate($im, 0, 0, 0);
    // 設置圓弧填充色
    $color_arc = imagecolorallocate($im, 255, 255, 255);
    // 在畫布上畫出圖像
    imagearc($im, 100, 100, 150, 150, 0, 360, $color_arc);
    // 輸出圖像
    header("Content-type: image/png");
    imagepng($im);
    // 關閉圖像資源
    imagedestroy($im);
    

    程序輸出結果:

    在這裏插入圖片描述

    繪製文字

    PHP中還提供了多個繪製文字的函數。

    1. imagechar水平地畫一個字符
      該函數定義如下:

      imagechar(resource $image, int $font, int $x, int $y, string $c, int $color):bool
      

      該函數將字符串c的第一個字符畫在image指定的圖像中,其左上角位於xy(圖像左上角爲0,0),顏色爲color。如果font是1,2,3,4,5,則使用內置字體(更大的數字對應於更大的子圖。)

      【示例】

      <?php
      // 第一步:創建畫布
      $im = imagecreate(100, 100);
      
      // 第二步:繪製圖像
      $string = 'PHP';
      // 定義背景色
      $bg = imagecolorallocate($im, 255, 255,255);
      // 定義字體顏色
      $font_color = imagecolorallocate($im, 0, 0, 0);
      // 在圖像的左上角打印一個黑色的P
      imagechar($im, 1, 40, 40, $string, $font_color);
      
      // 第三步:輸出圖像
      header('Content-type: image/png');
      imagepng($im);
      // 第四步:關閉圖像資源
      imagedestroy($im);
      

      程序輸出結果:

      在這裏插入圖片描述

    2. imagecharup()垂直地畫一個字符
      該函數語法格式與imagechar()相同,區別只是字符的方向不同,這裏不再累述。

    3. imagefttext()將文本寫入圖像
      該函數定義如下:

      imagefttext(resource $image, float $size, float $angle, int $x, int $y, int $color, string $fontfile, string $text[, array $extrainfo]):array
      

      該函數使用FreeType2字體將文本寫入圖像。

      參數:

      • image:由圖像穿件函數返回的圖像資源。
      • size:以像素點位點位的字體大小。
      • angle:角度(以度爲單位),0度表示從左向右輸出文本。較高的值表示逆時針旋轉。例如,值爲90將導致自下而上的輸出文本。
      • x,y:x和y給出的座標將定義第一個字符的基點(大致是字符的左下角)。這與imagestring()不同,後者中x和y定義第一個字符的左上角。
      • color:字體顏色。
      • fontfile:字體路徑。
      • text:輸出文本。

      【示例】

      <?php
      // 第一步:創建畫布
      $im = imagecreatetruecolor(300, 100);
      
      // 第二步:繪製圖像
      // 定義背景色
      $red = imagecolorallocate($im, 0xFF, 0x00, 0x00);
      // 定義字體顏色
      $black = imagecolorallocate($im, 0x00, 0x00, 0x00);
      // 畫一個紅色填充的矩形
      imagefilledrectangle($im, 0, 0, 299, 99, $red);
      // 定義字體路徑,(這裏的1.ttf與程序文件在同一目錄下)
      $font_file = '1.ttf';
      // 使用13號字,畫出字符串'I LOVE PHP'
      imagefttext($im, 30, 20, 55, 85, $black, realpath($font_file), "I LOVE PHP");
      
      // 第三步:輸出圖像
      header('Content-type: image/png');
      imagepng($im);
      // 第四步:關閉圖像資源
      imagedestroy($im);
      
      

      程序輸出結果:

      在這裏插入圖片描述

      注意:由於GD庫版本更新後,字體路徑需要使用絕對路徑,所以以上代碼中使用realpath()來獲得1.ttf的絕對路徑。

      同樣的,想讓該函數成功的輸出中文,需要指定中文字體。

    4. 使用TrueType字體處理中文生成圖片
      在PHP中有imagestring()imagefttext()等函數用來生成字符串圖片,但是它們支持的默認字體是十分有限的。TrueType字體是字體中極其常用的格式。PHP使用GD2庫,在windows環境下,需要給出TrueType字體所在的文件夾路徑,可以在程序開頭加入以下語句,引入系統字庫:
      putenv('GDFONTPATH=c:\WINDOWS\Fonts');
      使用TrueType字體也可以直接使用imagettftext()函數,即使用ttf字體的imagestring()函數,其定義如下:

      imagettftext(resource $image, float $size, float $angle, int $x, int $y, int $color, string $fontfile, string $text):array
      

      該函數使用TrueType字體將指定的text寫入圖像,函數返回一個含有8個元素的數組,分別表示了文本外框的四個角的座標,順序爲左下角、右下角、右上角、左上角。這些點相對於文本和角度無關,因此左上角指的是以水平方向看文字時其左上角。

      參數:

      • image:由圖像創建函數返回的圖像資源。
      • size:字體的尺寸。根據GD的版本,爲像素尺寸(GD1)或點(磅)尺寸(GD2)。
      • angle:角度,0度爲從左向右的文本。角度按逆時針旋轉。
      • x,y:定義了第一個字符的基本點(大概是字符的左下角)。
      • color:字體顏色。
      • fontfile:TrueType字體的路徑。
      • text:UTF-8編碼的文本字符串。可以包含十進制數字化字符表示(形式爲:&#8364;)來訪問字體中超過位置 127 的字符。UTF-8 編碼的字符串可以直接傳遞。 命名實體,比如&copy;是不支持的。可以考慮使用 html_entity_decode() 來解碼命名實體爲 UTF-8 字符。如果字符串中使用的某個字符不被字體支持,將使用一個空心矩形替換該字符。(也就是所謂的亂碼)

      【示例】

      <?php
      // 引入系統字庫
      putenv('GDFONTPATH=c:\WINDOWS\Fonts');
      // 定義畫布尺寸
      $xsize = 300;
      $ysize = 200;
      // 創建畫布
      $im = imagecreatetruecolor($xsize, $ysize);
      // 定義背景色
      $bg = imagecolorallocate($im, 8, 2, 133);
      // 定義字體顏色
      $font_color = imagecolorallocate($im, 230, 22, 22);
      // 填充畫布
      imagefill($im, 0, 0, $bg);
      // 定義字體
      $font_file = 'simhei.ttf';
      // 定義字符串
      $text = "這是一個把中文用黑體顯示的圖片。";
      // 如果你的編輯器使用的不是UTF-8編碼,則需要將中文編碼轉換爲UTF-8
      // $text = iconv("GB2312", "UTF-8", $text);
      // 將字符串畫到畫布上
      imagettftext($im, 12, 0, 20, 100,$font_color, $font_file, $text);
      
      // 輸出圖像
      header('Content-type: image/png');
      imagepng($im);
      
      // 關閉圖像資源
      imagedestroy($im);
      

      程序輸出結果:

      在這裏插入圖片描述

圖像處理

複製圖像

imagecopy()可用來複製圖像,其函數定義如下:

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):bool

該函數將src_im圖像中座標從src_xsrc_y開始,寬度爲src_w,高度爲src_h的一部分拷貝到dst_im圖像中座標爲dst_xdst_y的位置上。

【示例】

<?php
$imdst = imagecreatefromjpeg('2.jpg');
$imsrc = imagecreatefromjpeg('1.jpg');
imagecopy($imdst, $imsrc, 40, 50, 40, 50, 160, 100);
header('Content-type: image/jpeg');
imagejpeg($imdst);
imagedestroy($imdst);
imagedestroy($imsrc);

程序輸出結果:

原圖如下:1.jpg

在這裏插入圖片描述

2.jpg

在這裏插入圖片描述

程序輸出圖:

在這裏插入圖片描述

旋轉圖像

函數imagerotate()可將圖像旋轉一個給定的角度。函數定義如下:

imagerotate(resource $image, float $angle, int $bgd_color[, int $ignore_transparent = 0]):resource

該函數返回將src_im圖像用給定的angle角度旋轉後的圖像資源。bgd_color指定了旋轉後沒有覆蓋到的部分的顏色。旋轉的中心是圖像的中心,旋轉後的圖像會按比例縮小以適合目標圖像的大小——邊緣不會被剪去。

參數:

  • image:由圖像創建函數返回的圖像資源。
  • angle:旋轉角度,以逆時針方向旋轉圖像。
  • bgd_color:指定旋轉後覆蓋區域的顏色。
  • ignore_transparent:如果被設爲非零值,則透明色會被忽略(否則會被保留)。

【示例】

<?php
// 待旋轉的圖片文件名
$filename = '1.jpg';
// 旋轉角度
$degrees = 100;
// 定義HTTP頭
header('Content-type: image/jpeg');
// 加載圖像
$source = imagecreatefromjpeg($filename);
// 旋轉圖像
$rotate = imagerotate($source, $degrees, 0);
// 輸出旋轉後的圖像
imagejpeg($rotate);

// 關閉資源
imagedestroy($rotate);
imagedestroy($source);

程序輸出結果:

在這裏插入圖片描述

應用實例

圖像水印

圖像水印的原理就是把一張圖片複製到另一張背景圖片上。GD庫的imagecopymerge()函數,可以實現圖片水印,該函數定義如下:

imagecopymerge(resource $dst_im, resource $src_im, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_w, int $src_h, int $pct):bool

該函數將src_im圖像中座標從src_xsrc_y開始,寬度爲src_w,高度src_h的一部分拷貝到dst_im圖像中座標爲dst_xdst_y的位置上。兩圖像將根據pct來決定合併程度,其值範圍從0到100。當pct=0時,實際上什麼也沒做,當爲100時對於調色板圖像本函數和imagecopy()完全一樣,它對真彩色圖像實現了alpha透明。

【示例】

<?php
// 加載待添加水印的圖片
$imgdst = imagecreatefromjpeg('1.jpg');
// 創建水印圖像
$water = imagecreate(200, 50);
// 設置透明背景
$bg = imagecolorallocatealpha($water, 0, 0, 0, 127);
// 設置水印文字
$text = 'I am water';
// 設置文字顏色
$black = imagecolorallocate($water,255, 255, 255);
// 設置字體路徑
$font_file = '1.ttf';
// 關閉混合模式,以便透明顏色能覆蓋原畫板
imagealphablending($water, false);
// 用透明色填充背景
imagefill($water, 0, 0, $bg);
// 創建水印圖像
imagefttext($water, 12, 20,10, 48, $black, realpath($font_file), $text);
// 將水印加入圖片
imagecopymerge($imgdst, $water, 20, 200, 0, 0, 200, 50, 30);
// 輸出圖片
header('Content-type: image/jpeg');
imagepng($imgdst);

// 關閉圖像資源
imagedestroy($imgdst);
imagedestroy($water);

程序輸出結果:

在這裏插入圖片描述

圖像驗證碼

圖像驗證碼的原理就是生成一張圖片,然後在圖片上寫入字符,並輔之一些干擾元素(通常爲像素點和斜線)。圖像驗證碼經常用在用戶登陸、發帖等驗證場景中,其目的是爲了防止機器人(程序)自動操作,驗證此行爲來自用戶。

【示例】

<?php
function random($len) {
    // 組成驗證碼的字符集合,一般情況下會去掉01小寫l等容易混淆的字符
    $srcstr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789";
    // 設置隨機數種子
    mt_srand();
    $captcha_text = "";
    // 循環生成驗證碼字符串
    for ($i = 0; $i < $len; $i++) {
        $captcha_text .= $srcstr[mt_rand(0, strlen($srcstr))];
    }
    // 返回驗證碼字符串
    return strtoupper($captcha_text);
}
// 生成驗證碼字符串
$captcha = random(4);
// 設置驗證碼寬度
$width = 50;
// 設置驗證碼高度
$height = 25;
@header("Content-type:image/png");

// 創建驗證碼圖像
$im = imagecreate($width, $height);
// 設置背景色
$back = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);
// 模糊點顏色
$pix = imagecolorallocate($im, 187, 230, 247);
// 設置字體顏色
$font = imagecolorallocate($im, 41, 163, 238);
// 繪製模糊點
mt_srand();
for ($i = 0; $i < 1000; $i++) {
    imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $pix);
}
// 將驗證碼寫入圖片
imagestring($im, 5, 7, 5, $captcha, $font);
imagerectangle($im, 0, 0, $width-1, $height -1, $font);
imagepng($im);

// 關閉圖像資源
imagedestroy($im);

程序輸出結果:

在這裏插入圖片描述

以上代碼是爲了理解驗證碼生成的原理,下面給出一個驗證碼類,用面向對象的方式再實現驗證碼的生成,也算是複習一下面向對象的知識。

tips:建議以類名+.class+.php的方式來命名類文件

<?php
/**
 * 文件名:captcha.class.php
 * 驗證碼類
 */
class Captcha {
    private $width;     // 驗證碼寬度
    private $height;    // 驗證碼高度
    private $codeNum;   // 驗證碼中的字符數
    private $type;      // 驗證碼類型,0=數字,1=字母,2=字母+數字(默認值)
    private $font_file; // 驗證碼字體
    private $dot;       // 干擾點數量
    private $line;      // 干擾線數量
    private $image;     // 驗證碼圖像
    private $chars;     // 驗證碼字符串

    /* 構造函數 */
    function __construct($width=100, $height=40, $codeNum=4, $type=2, $session='captcha', $font_file='1.ttf', $dot=50, $line=4)
    {
        // 開啓session
        session_start();
        $this->width = $width;
        $this->height = $height;
        $this->codeNum = $codeNum;
        $this->type = $type;
        $this->session = $session;
        $this->font_file = $font_file;
        $this->dot = $dot;
        $this->line - $line;
        $this->image = $this->createCaptchaImage();
        $this->chars = $this->createCaptchaText();
        // 將生成的驗證碼放入session,以便用於驗證
        $_SEESION[$this->session] = $this->chars;
    }

    // 穿件驗證碼畫布
    private function createCaptchaImage(){
        $image = imagecreatetruecolor($this->width, $this->height);
        return $image;
    }

    // 生成隨機驗證碼字符串
    private function createCaptchaText(){
        switch ($this->type){
            case 0:
                $chars = implode('', range(0, 9));
                break;
            case 1:
                $chars = implode('', array_merge(range('A', 'Z'), range('a', 'z')));
                break;
            case 2:
                $chars = implode('', array_merge(range(0, 9), range('A', 'Z'), range('a', 'z')));
                break;
            default:
                break;
        }
        if (!empty($chars)) {
            $chars = str_shuffle($chars);   // 打亂字符排列順序
        }
        // 截取字符
        if ($this->codeNum > strlen($chars)) {
            exit('驗證碼長度超出限制!');
        }else {
            $chars = substr($chars, 0, $this->codeNum);
        }
        // 返回驗證碼字符串
        return $chars;
    }

    // 生成干擾元素
    private function interferon(){
        // 生成干擾線
        for ($i = 0; $i < $this->line; $i++) {
            // 生成隨機顏色
            $color = imagecolorallocate($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
            imageline($this->image, mt_rand(0, $this->width - 1), mt_rand(0, $this->height - 1), mt_rand(0, $this->width - 1), mt_rand(0, $this->height - 1), $color);
        }
        // 生成干擾點
        for ($i = 0; $i < $this->dot; $i++) {
            $color = imagecolorallocate($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
            imagesetpixel($this->image, mt_rand(0, $this->width - 1), mt_rand(0, $this->height - 1), $color);
        }
    }

    // 生成並輸出驗證碼圖像
    public function captcha($red=232, $green=155, $blue=55) {
        $color = imagecolorallocate($this->image, $red, $green, $blue);
        imagefilledrectangle($this->image, 0, 0, $this->width, $this->height, $color);
        for($i = 0; $i < $this->codeNum; $i++) {
            $size = mt_rand(16, 18);
            $angle = mt_rand(-15, 15);
            $x = 10 + $i * $size;
            $y = mt_rand(20, 26);
            $color = imagecolorallocate($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
            $text = substr($this->chars, $i, 1);
            imagettftext($this->image, $size, $angle, $x, $y, $color, realpath($this->font_file), $text);
        }
        $this->interferon();
        header('Content-type:image/gif');
        imagegif($this->image);
        imagedestroy($this->image);
    }
}

// 使用方法
$captcha = new Captcha();
$captcha->captcha();

程序輸出結果:

在這裏插入圖片描述

擴展——Jpgraph庫的使用

Jpgraph是一個功能強大且十分流行的PHP第三方圖片處理庫,其建立在內部庫文件GD2基礎之上。優點是建立了很多方便操作的對象和函數,能夠大大簡化使用GD庫對圖片進行處理的編碼過程。

Jpgraph庫的安裝配置

  1. 登陸Jpgraph官網 下載最新的Jpgraph壓縮包。
    在這裏插入圖片描述
  2. 將文件解壓,(推薦放到你項目目錄下)
  3. 修改php.ini文件:
    • 內存 memory_limit=X,至少爲32M
    • 執行時間max_execution_time=X,對於複雜的圖片加載時需要較多的時間,官方推薦爲30秒,可以根據圖片的複雜度做相應的修改
    • 在開發環境中註釋掉緩存output_buffering,便於調試,生產環境關閉。

使用Jpgraph創建圖形的一般姿勢

  1. 包含所需的類庫文件
    require_once();
  2. 初始化數據
    $data = array();
    這裏的數據可以是靜態的,也可以是動態的,也可以是通過GET或POST方法傳遞的。
  3. 創建Graph類實例
    $graph = new Graph();
    可以同時設置圖形的尺寸
  4. 設置標題、X軸標題、Y軸標題的內容,以及字體、顏色、位置等
  5. 創建對應的圖實例
    可以是折線圖、柱形圖、餅狀圖、3D圖等
  6. 將數據添加到圖形上
    $graph->Add();
  7. 顯示圖片
    $graph->Stroke();
  8. 解決中文亂碼Gpgraph默認顯示漢字時是把漢字編碼認爲gb2312,轉化爲utf-8以後再顯示,如果文件的編碼方式是gb2312,只需把SetFont()方法的第一個參數設置爲FF_SIMSUN即可如果是utf-8編碼的,需要先把漢字編碼轉化爲gb2312,這樣漢字才能正常顯示轉換編碼方式可以使用: iconv("UTF-8","gb2312",$x);

Jpgraph壓縮包中自帶了大量的demo,下面使用barlinealphaex1.php來說明其用法,該文件在Jpgraph庫的src/Example目錄下。其代碼如下:

<?php
// 包含文件需要修改
// 加載jpgraph的基本類庫
require_once ('jpgraph/src/jpgraph.php');
// 加載柱狀圖類庫
require_once ('jpgraph/src/jpgraph_bar.php');
// 加載折線圖類庫
require_once ('jpgraph/src/jpgraph_line.php');

// 定義柱狀圖和折線圖在Y軸上的數據座標,也是圖形展示的主要信息
$ydata  = array(10,120,80,190,260,170,60,40,20,230);
$ydata2 = array(10,70,40,120,200,60,80,40,20,5);

// 定義了月份使用短格式顯示
$months = $gDateLocale->GetShortMonth();

// 創建圖形$graph,寬300,高200
$graph = new Graph(300,200);
// 設置刻度爲自動生成的刻度形式
$graph->SetScale("textlin");
// 設置圖形邊框顏色爲白色
$graph->SetMarginColor('white');

// 調整邊框寬度
$graph->SetMargin(30,1,20,5);

// 在背景圖上添加邊框
$graph->SetBox();

// 取消整個圖片的邊框
$graph->SetFrame(false);

// 設置標題和字體
$graph->tabtitle->Set('Year 2003');
$graph->tabtitle->SetFont(FF_ARIAL,FS_BOLD,10);

// 設置x座標,y座標的顏色、字體和是否顯示
$graph->ygrid->SetFill(true,'#[email protected]','#[email protected]');
$graph->ygrid->SetLineStyle('dashed');
$graph->ygrid->SetColor('gray');
$graph->xgrid->Show();
$graph->xgrid->SetLineStyle('dashed');
$graph->xgrid->SetColor('gray');

// 使用$months變量中的數據設置X軸顯示字體及角度
$graph->xaxis->SetTickLabels($months);
$graph->xaxis->SetFont(FF_ARIAL,FS_NORMAL,8);
$graph->xaxis->SetLabelAngle(45);

// 使用$ydata數據生成柱狀圖,定義柱狀圖的寬度爲0.6,
$bplot = new BarPlot($ydata);
$bplot->SetWidth(0.6);
$fcol='#440000';
$tcol='#FF9090';
// 填充柱狀圖,並且使用填充的漸變樣式和兩個漸變的顏色。
$bplot->SetFillGradient($fcol,$tcol,GRAD_LEFT_REFLECTION);

// Set line weigth to 0 so that there are no border
// around each bar
$bplot->SetWeight(0);

$graph->Add($bplot);

// 使用$ydata2數據生成折線圖
$lplot = new LinePlot($ydata2);
$lplot->SetFillColor('[email protected]');
$lplot->SetColor('[email protected]');
$lplot->SetBarCenter();

$lplot->mark->SetType(MARK_SQUARE);
$lplot->mark->SetColor('[email protected]');
$lplot->mark->SetFillColor('lightblue');
$lplot->mark->SetSize(6);

$graph->Add($lplot);

// 將圖像輸出到瀏覽器
$graph->Stroke();
?>

程序輸出結果:

在這裏插入圖片描述

該第三方庫還有許多其他圖形,請自行研究吧。

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