核心編程筆記 繪畫 驗證碼 水印 縮略圖

1.繪畫的基本操作

1.1前提

默認PHP 是不支持繪畫技術,需要我們開啓PHP的擴展

但我個人的wamp64的php.ini裏的gd2是默認開着的

使用phpinfo()函數可顯示PHP配置,可查看gd

1.2創建畫布 imagecreatetruecolor(w,h)

imagecreatetruecolor(w,h); -
w 表示的是所要創建的畫布的寬
h 表示的是所要創建的畫布的高

如果創建成功返回的一個gd資源:resource(2, gd)

1.3分配顏色 imagecolorallocate(img,r,g,b);

imagecolorallocate(img,r,g,b); -
img 畫布資源(gd資源)
r,g,b 十進制的顏色表示方式(紅、綠、藍三色)

此函數僅是創建了一個顏色資源,但並沒有使用

1.4填充顏色 imagefill(img,x,y,color);

imagefill(img,x,y,color); -
img 畫布資源
x,y 畫布上的某個點
color 所要填充的顏色
//1.創建畫布
$w=400;
$h=200;
$img=imagecreatetruecolor($w,$h);

//2.分配顏色
$bg=imagecolorallocate($img,255,89,87);

//3.爲畫布填充顏色
imagefill($img,0,0,$bg);

//4.顯示畫布
header('content-type:image/jpeg');
imagejpeg($img);

1.5基本圖形的繪製

1.5.1 繪製矩形 imagerectangle(img,x1,y1,x2,y2,color)

imagerectangle(img,x1,y1,x2,y2,color); -
rectangle1 矩形
img 畫布資源
x1,y1 左上角頂點座標
x2.y2 右下角頂點座標
color 所要繪製的矩形邊線的顏色

1.5.2 繪製直線 imageline(img,x1,y1,x2,y2,color)

imageline(img,x1,y1,x2,y2,color); -
img 畫布資源
x1,y1 所要繪製的直線的起點座標
x2.y2 所要繪製的直線的終點座標
color 直線的顏色

1.5.3 繪製字母 imagestring(img,size,x,y,string,color)

imagestring(img,size,x,y,string,color); -
img 畫布資源
size 文字大小,0到5個等級
x,y 所要繪製位置
string 所要繪製的內容
color 所要繪製的內容的顏色

imagestring只適合繪製字母,不能繪製漢字,不能選擇字體,不能設置繪製的角度

1.5.4 繪製漢字 imagesttftext(img,size,angle,x,y,string,color,font,text)

imagesttftext(img,size,angle,x,y,string,color,font,text); -
img 畫布資源
size 大小,單位像素
angle 角度
x,y 所要繪製的內容的左下角座標
string 所要繪製的內容
color 所要繪製的內容的顏色
font 所要繪製的內容的字體,字體文件名前需加絕對路徑
text 所要繪製的內容

window操作系統的字體位於c:/windows/fonts目錄內

特別說明:本人嘗試了許久,font參數的文件必須寫絕對路徑,否則gd庫無法找到字體,絕對路徑可以用realpath()函數轉換

imagettftext(img,20,30,150,50,img,20,-30,150,50,color,==realpath(font)==,font)==,text);

1.6輸出畫布

imagejpeg(img【,filename】);

imagepng(img【,filename】);

imagegif(img【,filename】);

filename表示是所要保存的文件名,可以省略,如果省略表示輸出到瀏覽器

在輸出到瀏覽器之前必須設置header(‘content-type:image/gif’)

在將畫布輸出到瀏覽器時,不要有任何多餘的輸出

如果無法顯示圖片,需要將header()註釋掉纔可以看到錯誤信息

1.7從圖片創建畫布 imagecreatefromjpeg();

imagecreatefromjpeg(); imagecreatefrompng(); imagecreatefromgif();

$file=realpath('jietu.jpg');//依然需要絕對路徑
$img=imagecreatefrompng($file);
//var_dump($img);//測試是否接收到gd資源
header('content-type:image/jpeg');

file是所要讀取的文件

以上函數會根據file圖片的寬高來創建一個畫布,並將圖片的原內容讀取到畫布中。

什麼樣類型的圖片就必須使用相應的類型函數

$file=realpath('ok.png');
$info=getimagesize($file);  //利用getimagesize()函數。

switch ($info['mime']){
    case 'image/jpeg':
        $img=imagecreatefrompng($file);
        break;
    case 'image/png':
        $img=imagecreatefrompng($file);
        break;
    case 'image/gif':
        $img=imagecreatefromgif($file);
        break;
}
header('content-type:image/jpeg');
imagepng($img);

2驗證碼

2.1什麼是驗證碼

CAPTCHA 全自動區分人與計算機的圖靈測試

計算機可以獲取頁面上html中的信息,但是不能獲取圖片上的文字信息,想獲取必須藉助人眼識別信息

2.2作用

驗證碼用於區分計算機與人,爲了降低在很少的時間內對我們站點的一個訪問頻率

原理:就是將一組隨機生成的字符串畫到畫布上

2.3製作驗證碼

2.3.1生成隨機字符串

function getCode(){
    $charset='qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789';
    $code='';
    for ($i=0;$i<4;$i++){
        $code .= $charset[mt_rand(0,strlen($charset)-1)];
    }
    return $code;
}
echo getCode();

2.3.2 繪製驗證碼

//創建畫布
$w=100;
$h=30;
$img=imagecreatetruecolor($w,$h);

//2.填充背景顏色
$bg=imagecolorallocate($img,mt_rand(210,255),mt_rand(210,255),mt_rand(210,255));
imagefill($img,0,0,$bg);

//3.繪製隨機驗證碼
$code=getCode();
for ($i=0;$i<strlen($code);$i++) {
    $color=imagecolorallocate($img,mt_rand(100,200),mt_rand(100,200),mt_rand(100,200));
    imagettftext($img, mt_rand(18, 26), mt_rand(-20, 20), 18*($i+1), 25, $color, realpath('../public/simkai.ttf'), $code[$i]);
}
//4.增加干擾線
for($i=0;$i<4;$i++){
    $color=imagecolorallocate($img,mt_rand(100,200),mt_rand(100,200),mt_rand(100,200));
    imageline($img,mt_rand(0,100),mt_rand(0,30),mt_rand(0,100),mt_rand(0,30),$color);
}
//測試
header('content-type:image/jpeg');
imagejpeg($img);

2.4封裝驗證碼函數

$w=100;
$h=30;
$len=4;
captcha($w,$h,$len);
function captcha($w,$h,$len)
{
    //創建畫布
    $img = imagecreatetruecolor($w, $h);

    //2.填充背景顏色
    $bg = imagecolorallocate($img, mt_rand(210, 255), mt_rand(210, 255), mt_rand(210, 255));
    imagefill($img, 0, 0, $bg);

    //3.繪製隨機驗證碼
    $code = getCode($len);
    for ($i = 0; $i < strlen($code); $i++) {
        $color = imagecolorallocate($img, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
        imagettftext($img, mt_rand(18, 26), mt_rand(-20, 20), 18 * ($i + 1), 25, $color, realpath('../public/simkai.ttf'), $code[$i]);
    }
    //4.增加干擾線
    for ($i = 0; $i < 4; $i++) {
        $color = imagecolorallocate($img, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
        imageline($img, mt_rand(0, 100), mt_rand(0, 30), mt_rand(0, 100), mt_rand(0, 30), $color);
    }
    //測試
    header('content-type:image/jpeg');
    imagejpeg($img);
}
//生成隨機字符串
function getCode($len){
    $charset='qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789';
    $code='';
    for ($i=0;$i<$len;$i++){
        $code .= $charset[mt_rand(0,strlen($charset)-1)];
    }
    return $code;
}

2.5驗證碼應用

2.5.1 分析

驗證碼是以圖片的形式顯示在頁面上,在頁面上img標籤

img標籤的src屬性,可以指向服務器的一個已經存在的圖片的路徑,也可以是一個PHP文件

但這個PHP文件要能夠生產圖片

2.5.2 login.html中展示驗證碼的img標籤的src屬性指向captcha.php文件

2.5.3 點擊驗證碼刷新

==圖片1==

<img id="code" class="pull-right img-rounded" 
style="border: 1px solid #ccc;" width="100;"
src="captcha.php" onclick="this.src='captcha.php?'+Math.random()">

2.5.4 校驗驗證碼

過程:就用戶輸入的驗證碼與服務器產生的驗證碼進行比較

由於產生驗證碼的文件是captcha.php,而對驗證碼進行比較是在另一個validte.php文件,這就涉及到在不同的腳本(PHP)中使用數據

  1. 在產生驗證碼的captcha.php文件中將驗證碼字符串寫到$_SESSION中
 //將隨機生成的驗證碼寫入session
    session_start();
    $_SESSION['code']=$code;
  1. 在validte.php文件中讀取即可
//從session中讀取驗證碼字符串
session_start();
$code=$_SESSION['code'];
if (strtolower($verify)!=strtolower($code)){
    header('location:login.php');
    exit;
}

3.水印

3.1.水印的作用

版本保護

宣傳目的

3.2.水印的原理

在用戶的圖片上,“印上”公司的logo或寫上公司的名、網址

3.3.製作水印

imagecopymerge(dest,src,d_x,d_y,s_x,s_y,s_w,s_h,op);

- -
dest 目標圖片(用戶圖片)
src 原圖片(公司logo)
d_x,d_y 目標圖片上的某個點
s_x,s_y 原圖片上的某個點
s_w,s_h 表示寬高
op 表示透明度

在src圖片從s_x,s_y爲起點,複製s_w爲寬,s_h爲高的區域,放在dest圖片以d_x,d_y表示的一個點上

3.3.1簡單實現

//用戶上傳的圖片
$dest='th.jpg';
//logo圖片
$src='logo.png';    //src_w:60,src_h:55

//將已有的圖片讀取到畫布中
$imgDest=imagecreatefromjpeg($dest);
$imgSrc=imagecreatefrompng($src);

//製作水印
imagecopymerge($imgDest,$imgSrc,0,0,0,0,60,54,50);

header('content-type:image/png');
imagepng($imgDest);

3.3.2完善

//用戶上傳的圖片
$dest='th.jpg';
//logo圖片
$src='logo.png';    //src_w:60,src_h:55
$infoSrc=getimagesize($src);

//將已有的圖片讀取到畫布中
$imgDest=createFrom($dest);
$imgSrc=createFrom($src);

//製作水印
imagecopymerge($imgDest,$imgSrc,0,0,0,0,$infoSrc[0],$infoSrc[1],50);

header('content-type:image/png');
imagepng($imgDest);

//封裝由圖片創建畫布的函數
function createFrom($file){
   
}

3.4.封裝水印函數

//用戶上傳的圖片
$dest='th.jpg';
//logo圖片
$src='logo.png';    //src_w:60,src_h:55

water($dest,$src,4,50);
/**
 * @param1 $dest string 用戶圖片
 * @param2 $src string logo
 * @param3 $op int 透明度
 * @param4 int 表示logo的位置 1:左上角 2:右上角 3:左下角 4:右下角 5.中間
 */
function water($dest,$src,$pos,$op)
{
    $infoSrc = getimagesize($src);
    $infoDest= getimagesize($dest);

//將已有的圖片讀取到畫布中
    $imgDest = createFrom($dest);
    $imgSrc = createFrom($src);

    switch ($pos){
        case 1:
            $d_x=0;
            $d_y=0;
            break;
        case 2:
            $d_x=$infoDest[0]-$infoSrc[0];
            $d_y=0;
            break;
        case 3:
            $d_x=0;
            $d_y=$infoDest[1]-$infoSrc[1];
            break;
        case 4:
            $d_x=$infoDest[0]-$infoSrc[0];
            $d_y=$infoDest[1]-$infoSrc[1];
            break;
        case 5:
            $d_x=($infoDest[0]-$infoSrc[0])/2;
            $d_y=($infoDest[1]-$infoSrc[1])/2;
            break;
    }

//製作水印
    imagecopymerge($imgDest, $imgSrc, $d_x, $d_y, 0, 0, $infoSrc[0], $infoSrc[1], $op);

    header('content-type:image/png');
    imagepng($imgDest);
}

//封裝由圖片創建畫布的函數
function createFrom($file){
    $info = getimagesize($file);
    switch ($info['mime']) {
        case  'image/jpeg':
            $img = imagecreatefromjpeg($file);
            break;
        case  'image/png':
            $img = imagecreatefrompng($file);
            break;
        case  'image/gif':
            $img = imagecreatefromgif($file);
            break;
    }
    return $img;
}

4.縮略圖

4.1.作用

節省帶寬

增加用戶體驗度

4.2.原理

將用戶圖片等比例放到一個給定的畫布中

4.3.製作縮略圖

imagecopyresamepled(dest,src,d_x,d_y,s_x,s_y,d_w,d_h,s_w,s_h);

- -
dest 目標圖片(框)
src 用戶圖片
d_x,d_y 目標圖片上的某個點
d_w,d_h 表示寬、高
s_x,s_y 用戶圖片上的某個點
s_w,s_h 表示寬高
op 表示透明度

在src圖片從s_x,s_y爲起點,截取以s_w爲寬,s_h爲高的區域,放在dest畫布上以d_x,d_y爲頂點,以d_w爲寬,d_h爲高的區域

4.4.封裝縮略圖處理函數

//測試數據
$d_w = 500;
$d_h = 300;
$src = "th.jpg";
thumb($d_w,$d_h,$src);
function thumb($d_w,$d_h,$src)
{
//創建畫布(框)
    $imgDest = imagecreatetruecolor($d_w, $d_h);//框
    $bg = imagecolorallocate($imgDest, 161, 130, 190);
    imagefill($imgDest, 0, 0, $bg);

//由用戶圖片創建畫布
    $infoSrc = getimagesize($src);
    $s_w = $infoSrc[0];
    $s_h = $infoSrc[1];
    $imgSrc = createFrom($src);

    $f_h = $d_h;
    $f_w = $s_w / $s_h * $f_h;
    if ($f_w > $d_w) {
        $f_w = $d_w;
        $f_h = $s_h / $s_w * $f_w;
    }

//計算imgDestin上所放置的起點位置
    $posX = ($d_w - $f_w) / 2;
    $posY = ($d_h - $f_h) / 2;

//採樣合併
    imagecopyresampled($imgDest, $imgSrc, $posX, $posY, 0, 0, $f_w, $f_h, $s_w, $s_h);
    header('content-type:image/jpeg');
    imagejpeg($imgDest);
}

//封裝由圖片創建畫布的函數
function createFrom($file)
{
    $info = getimagesize($file);
    switch ($info['mime']) {
        case  'image/jpeg':
            $img = imagecreatefromjpeg($file);
            break;
        case  'image/png':
            $img = imagecreatefrompng($file);
            break;
        case  'image/gif':
            $img = imagecreatefromgif($file);
            break;
    }
    return $img;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章