11.GD圖像處理

思考:在PHP開發(fā)中,應(yīng)該會經(jīng)常用到圖形處理之類的,那么PHP能夠處理圖片嗎?

引入:PHP作為一款強(qiáng)大的后臺處理語言,操作圖片是必不可少的,PHP本身不操作圖片,但是可以借助強(qiáng)大的擴(kuò)展庫實(shí)現(xiàn)圖片的操作。PHP主要使用GD庫實(shí)現(xiàn)圖片操作。

  • 驗(yàn)證碼制作
  • 縮略圖
  • 水印圖

總結(jié):PHP可以利用GD庫進(jìn)行各種圖像操作


1. 加載GD庫【掌握】

  1. GD庫作為一種擴(kuò)展項(xiàng),需要事先加載才能使用,加載的方式就是在php.ini中開啟GD擴(kuò)展


    加載GD擴(kuò)展.png
  1. GD庫加載后,內(nèi)置了很多函數(shù)供開發(fā)人員操作,可以通過操作手冊索引中輸入image來檢索
操作手冊查看GD函數(shù).png
  1. 常用的GD函數(shù)列表
  • imagecreatetruecolor:創(chuàng)建一張真彩畫布
  • imagecolorallocate:給畫布分配顏色
  • imagefill:填充顏色
  • imagestring:水平寫字符串(ASCII碼)
  • imagettftext:文本寫入
  • imageline:制作線段
  • imagecreatefromjpeg:打開一張jpeg圖片
  • imagecreatefrompng:打開一張png圖片
  • imagecopymerge:拷貝圖像合并到另外一張圖片資源
  • imagecopyresampled:不失真拷貝圖片到另外一張圖片資源
  • imagepng:保存或者輸出圖片,保存格式為png
  • imagejpeg:保存或者輸出圖片,保存格式為jpeg
  • imagedestroy:銷毀資源
  • getimagesize:取得圖片信息
  • pathinfo:得到文件信息

總結(jié)

  1. GD庫提供了很多函數(shù)來處理圖片
  2. 根據(jù)不同的需求可以使用不同的函數(shù)來完成對應(yīng)的功能
  3. 列出了制作驗(yàn)證碼、水印和縮略圖所需要的常用函數(shù)

思考:驗(yàn)證碼圖片是怎么做成的呢?

引入:在開發(fā)中,幾乎所有的網(wǎng)站都有用到驗(yàn)證碼功能,驗(yàn)證碼不是一個(gè)簡單的字符串,通常都是將字符串放到圖片上,而且加上很多干擾內(nèi)容來完成。

2. 制作驗(yàn)證碼【掌握】

定義驗(yàn)證碼(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自動區(qū)分計(jì)算機(jī)和人類的圖靈測試)的縮寫 ,是一種區(qū)分用戶是計(jì)算機(jī)還是人的公共全自動程序。驗(yàn)證碼由最初的簡單字符串到現(xiàn)在各式各樣復(fù)雜的圖片、計(jì)算、問題等,只是因?yàn)橛?jì)算機(jī)識別的功能已經(jīng)越來越強(qiáng)大。

  1. 驗(yàn)證碼制作流程
  • 制作畫布:imagecreatetruecolor
  • 填充背景色:imagecolorallocate分配顏色,imagefill填充顏色
  • 寫入內(nèi)容:imagestring寫簡單內(nèi)容,imagettftext寫入字體文字
  • 增加干擾:imageline增加線段,imagestring增加其他符號
  • 保存圖片:imagepng輸出或者保存圖片
  1. 簡單圖片制作
<?php
//制作簡單圖片

//1.創(chuàng)建畫布
$img = imagecreatetruecolor(200,200);   //寬度和高度,像素單位,得到畫布資源

//2.輸出圖片
header('content-type:image/png');
imagepng($img);                       //所有g(shù)d函數(shù)都需要圖片資源

//3.銷毀資源
imagedestroy($img);
  1. 簡單驗(yàn)證碼制作
<?php
    
//制作簡單驗(yàn)證碼圖片
    
//1.創(chuàng)建畫布資源
$img = imagecreatetruecolor(100,30);

//2.填充背景色
//2.1給畫布分配背景顏色
$bg_color = imagecolorallocate($img,255,255,255);   #RGB三色組,純白色

//2.2填充顏色
imagefill($img,0,0,$bg_color);                     #從0,0坐標(biāo)處開始上色,自動渲染相同顏色像素點(diǎn)

//3.寫入字符串
//3.1給要寫入的字符串分配顏色
$str_color = imagecolorallocate($img,150,150,150);  #比背景顏色稍深
//3.2寫入文字
imagestring($img,5,30,10,'capcha',$str_color);

//4.保存輸出
//4.1保存
imagepng($img,'captcha.png');                      #保存到當(dāng)前文件夾captcha.png
//4.2輸出
header('content-type:image/png');
imagepng($img);

//5.銷毀資源
imagedestroy($img);
  1. 封裝簡單驗(yàn)證碼制作函數(shù)
<?php
//封裝驗(yàn)證碼制作函數(shù)

/*
 * 驗(yàn)證碼制作函數(shù)
 * @param1 int $width 圖片寬度
 * @param2 int $height 圖片高度
 * @param3 int $lines = 10,干擾線數(shù)量,默認(rèn)10條
 * @param4 int $length = 4 字符串長度,默認(rèn)4個(gè)簡單字符
 
*/
function getCaptcha($width,$height,$lines = 10,$length = 4){
    //1.制作畫布
    $img = imagecreatetruecolor($width,$height);
    
    //2.填充背景
    $bg_c = imagecolorallocate($img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)); #隨機(jī)淡色
    imagefill($img,0,0,$bg_c);
    
    //3.制作隨機(jī)字符串
    $str_arr = range('A','Z');          #得到A-Z數(shù)組元素
    shuffle($str_arr);                  #打亂數(shù)組元素
    
    //定義一個(gè)字符串保留取出的所有字母
    $captcha = '';
    //循環(huán)取元素即可
    for($i = 0;$i < $length; $i++){
        //每取出一個(gè)符號就保留到$captcha
        $captcha .= $str_arr[$i];       #取亂序數(shù)組前4個(gè)元素
    }
    
    //寫入圖片
    $str_c = imagecolorallocate($img,mt_rand(0,100),mt_rand(0,100),mt_rand(0,100)); #隨機(jī)深色
    imagestring($img,5,30,10,$captcha,$str_c);
    
    //4.制作干擾元素
    //循環(huán)制作多條
    for($i = 0;$i < $lines;$i++){
       $line_c = imagecolorallocate($img,mt_rand(120,180),mt_rand(120,180),mt_rand(120,180)); #中間顏色,每條顏色都不一樣
        imageline($img,mt_rand(0,$width),mt_rand(0,$height),mt_rand(0,$width),mt_rand(0,$height),$line_c); #隨機(jī)起始位置
    }
    
    //5.輸出圖片
    header('content-type:image/png');
    imagepng($img);
    
    //6.銷毀資源
    imagedestroy($img);
}

總結(jié)

  1. 驗(yàn)證碼指的是印在圖片上的隨機(jī)字符
  2. 驗(yàn)證碼圖片的制作流程:畫布->背景色->隨機(jī)字符串->寫入字符串->干擾->輸出圖片->銷毀畫布
  3. 驗(yàn)證碼的功能可以很豐富,需要使用更加復(fù)雜的函數(shù)和邏輯

思考:隨著版權(quán)意識越來越高,很多人已經(jīng)開始給自己的圖片做了版權(quán)保護(hù)處理,就是在上面增加了一些若影若現(xiàn)的文字或者圖片,這個(gè)怎么實(shí)現(xiàn)呢?

引入:圖片上加入內(nèi)容,其實(shí)就是制作水印的一個(gè)過程。驗(yàn)證碼也可以理解為是一個(gè)帶文字水印的圖片。更多的水印是通過放置一張圖片到上面來實(shí)現(xiàn)的。

3. 制作水印圖片【掌握】

定義:制作水印圖片,就是往一張圖片上放入一些文字或者圖片元素,在不是特別影響原圖的使用的前提下,又能有版權(quán)追溯(防止別人盜圖商用)。

  1. 水印制作流程(圖片版)
  • 打開原圖:imagecreatefromjpeg/png,從jpeg(基本上都是)打開原圖資源
  • 打開水印圖:與原圖一樣,只是圖片通常是png
  • 復(fù)制水印圖合并到原圖上:imagecopymerge
  • 保存圖片:imagejpeg/png
  • 關(guān)閉資源
  1. 實(shí)現(xiàn)水印圖(原圖desktop.jpg,水印圖php.png)
<?php
//制作水印圖

//1.打開要添加水印圖的資源
$dst = imagecreatefromjpeg('desktop.jpg');

//2.打開水印圖片資源
$src = imagecreatefrompng('php.png');

//3.采樣復(fù)制合并:全部水印圖放到原圖左上角
$src_info = getimagesize('php.jpg'); #獲取圖片信息返回?cái)?shù)組,0元素為寬,1元素為高
imagecopymerge($dst,$src,0,0,0,0,$src_info[0],$src_info[1],50); #透明度50

//4.保存圖片
header('content-type:image/jpeg');
imagejpeg($dst);
imagejpeg($dst,'water.jpg');

//5.銷毀資源
imagedestroy($dst);
imagedestroy($src);
  1. 封裝水印圖制作函數(shù)
<?php
    
//封裝水印圖制作函數(shù)
/*
 * 制作水印圖
 * @param1 string $image,要添加水印的圖片地址
 * @param2 string $path,水印圖制作完成后存儲路徑
 * @param3 string $water,水印圖圖片地址
 * @param4 int $pct = 50,透明度,默認(rèn)50
 * @return string 新生成圖片的名字
*/
function getWatermark($image,$path,$water,$pct = 50){
    //1.打開原圖資源
    $dst = imagecreatefromjpeg($image);
    
    //2.打開水印圖資源
    $src = imagecreatefrompng($water);
    
    //3.采樣復(fù)制合并:存放到做上角(不需要計(jì)算)
    $src_info = getimagesize($water);       
    imagecopymerge($dst,$src,0,0,0,0,$src_info[0],$src_info[1],$pct);
    
    //4.保存圖片
    //獲取原圖片路徑和名字信息
    $image_info = pathinfo($image); #返回?cái)?shù)組:extension是后綴名,filename是純名字
    //拼湊新文件名字
    $water_name = $image_info['filename'] . '_water' . '.' . $image_info['extension'];
    imagejpeg($dst,$path . '/' . $water_name);
    
    //5.銷毀資源
    imagedestroy($dst);
    imagedestroy($src);
    
    //6.返回文件名
    return $water_name;
}

總結(jié)

  1. 水印圖分為文字水印圖(驗(yàn)證碼)和圖片水印圖
  2. 水印圖的制作流程:打開原圖->打開水印圖->采樣復(fù)制合并->保存圖片->銷毀資源
  3. 水印圖不像驗(yàn)證碼,一般是規(guī)定位置規(guī)定水印圖樣章的

思考:在很多網(wǎng)站上,上傳圖片的時(shí)候都會有個(gè)小圖可以看的,那么是怎么實(shí)現(xiàn)的呢?

引入:其實(shí)小圖的本質(zhì)并不是用戶上傳的,而是系統(tǒng)根據(jù)系統(tǒng)需求在用戶上傳原圖的時(shí)候,制作的一個(gè)小圖。這個(gè)小圖就是縮略圖。

4. 制作縮略圖【掌握】

定義:制作縮略圖,就是將原圖放到一個(gè)固定的大小的圖片資源里,形成一張新的圖片。通常是把大圖做成小圖,因此叫做縮略圖。

  1. 縮略圖制作原理
  • 打開原圖資源:imagecreatefromjpeg
  • 創(chuàng)建縮略圖資源:imagecreatetruecolor
  • 采樣復(fù)制合并:imagecopyresampled(不失真)
  • 保存縮略圖資源:imagejpeg(較多)
  • 銷毀資源
  1. 實(shí)現(xiàn)縮略圖
<?php
    
//制作縮略圖
//1.打開原圖資源
$src = imagecreatefromjpeg('desktop.jpg');

//2.創(chuàng)建縮略圖資源
$dst = imagecreatetruecolor(100,100);

//3.采樣復(fù)制合并
$src_info = getimagesize('desktop.jpg');
imagecopyresampled($dst,$src,0,0,0,0,100,100,$src_info[0],$src_info[1]);

//4.保存輸出
header('content-type:image/jpeg');
imagejpeg($dst);
imagejpeg($dst,'desktop_thumb.jpg');

//5.銷毀資源
imagedestroy($src);
imagedestroy($dst);
  1. 縮略圖注意事項(xiàng):原圖與縮略圖比例不一樣采用全部填充滿,會導(dǎo)致縮略圖“變形”,這種時(shí)候的解決方案如下
  • 求出原圖的寬高比
  • 求出縮略圖的寬高比
  • 比較原圖的寬高比和縮略圖的寬高比
    • 原圖寬高比大于縮略圖寬高比,說明原圖太寬,應(yīng)該讓縮略圖的寬占滿,高按比例求出來
    • 原圖寬高比小于縮略圖寬高比,說明原圖太高,應(yīng)該讓縮略圖的高占滿,寬按比例求出來
  • 不管哪種情況,勢必會有縮略圖部分區(qū)域沒有放上內(nèi)容,這個(gè)時(shí)候縮略圖背景填充為白色(補(bǔ)白)
  • 根據(jù)計(jì)算出來的實(shí)際寬高像素,將圖片居中到縮略圖中
  1. 制作縮略圖函數(shù)(補(bǔ)白)
<?php
    
//制作補(bǔ)白效果縮略圖

/*
 @param1 string $image,原圖地址
 @param2 string $path,縮略圖存儲路徑
 @param3 int $width = 100,縮略圖寬
 @param4 int $height = 100,縮略圖高
*/
function getThumb($image,$path,$width = 100,$height = 100){
    //1.打開原圖資源
    $src = imagecreatefromjpeg($image);
    
    //2.創(chuàng)建縮略圖畫布
    $thu = imagecreatetruecolor($width,$height);
    
    //3.補(bǔ)白:背景填充白色
    $white = imagecolorallocate($thu,255,255,255);
    imagefill($thu,0,0,$white);
    
    //4.計(jì)算縮略圖所放圖片的實(shí)際寬和高:通過原圖寬高比和縮略圖寬高比來比較
    $src_info = getimagesize($image);
    
    //原圖寬高比
    $src_c = $src_info[0] / $src_info[1];
    $thu_c = $width / $height;
    
    //判定
    if($src_c > $thu_c){
        #原圖寬高比大于縮略圖,說明原圖很寬,那么縮略圖中寬度應(yīng)該占滿
        $thu_w = $width;    #占滿縮略圖寬
        $thu_h = ceil($thu_w / $src_c); #取整
    }else{
        #原圖寬高比小于縮略圖,說明原圖很高,那么縮略圖中高度應(yīng)該占滿
        $thu_h = $height;
        $thu_w = ceil($thu * $src_c);
    }
    
    //5.采樣復(fù)制粘貼:還需讓縮略圖居中
    $x = ceil(abs($thu_w - $width) / 2);    //絕對值除以2取整
    $y = ceil(abs($thu_h - $height) / 2);
    imagecopyresampled($thu,$src,$x,$y,0,0,$thu_w,$thu_h,$src_info[0],$src_info[1]);
    
    //6.保存圖片
    $image_info = pathinfo($image);
    //構(gòu)造新文件名字
    $newname = $image_info['filename'] . '_thumb' . '.' . $image_info['extension'];
    
    imagejpeg($thu,$path . '/' . $newname);
    
    //7.銷毀資源
    imagedestroy($src);
    imagedestroy($thu);
    
    //8.返回結(jié)果
    return $newname;
}

總結(jié)

  1. 縮略圖是在用戶上傳原圖的時(shí)候系統(tǒng)根據(jù)需求自動生成的
  2. 縮略圖要保證與原圖比例一致,就需要進(jìn)行縮略圖中圖片實(shí)際的尺寸,并進(jìn)行補(bǔ)白
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • PHP中GD庫的使用 GD簡介 PHP 不僅限于只產(chǎn)生 HTML 的輸出,還可以創(chuàng)建及操作多種不同格式的圖像文件。...
    dptms閱讀 1,087評論 0 2
  • 夕陽加快了步伐 希望生一場清風(fēng) 奔跑在剛到的悶熱的五月里 那如清水的彎月 也滌不去我一天滴淌的辛勞 我前面的身影 ...
    見芳齋閱讀 220評論 0 5
  • 看看言情小說,看看偶像劇,日常沉迷于虛假的男主腹黑或溫暖中,幻想自己是那個(gè)萬千寵愛集一身的女主。應(yīng)該是小女生的通病...
    瑾_jessica閱讀 227評論 0 0
  • 這一周過得中規(guī)中矩! 端午回來,節(jié)前上報(bào)的牛奶沒及時(shí)拿,我得抓緊。周二...
    fef73b8af426閱讀 222評論 0 0
  • 接到老師的電話,說要來家訪,激動又興奮,約定好了時(shí)間,去奶奶家接兒子、將家里打掃的一塵不染,為此午飯都沒...
    泥道至簡閱讀 287評論 0 0

友情鏈接更多精彩內(nèi)容