思考:在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庫【掌握】
-
GD庫作為一種擴(kuò)展項(xiàng),需要事先加載才能使用,加載的方式就是在php.ini中開啟GD擴(kuò)展
加載GD擴(kuò)展.png
- GD庫加載后,內(nèi)置了很多函數(shù)供開發(fā)人員操作,可以通過操作手冊索引中輸入
image來檢索

- 常用的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é)
- GD庫提供了很多函數(shù)來處理圖片
- 根據(jù)不同的需求可以使用不同的函數(shù)來完成對應(yīng)的功能
- 列出了制作驗(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)大。
- 驗(yàn)證碼制作流程
- 制作畫布:imagecreatetruecolor
- 填充背景色:imagecolorallocate分配顏色,imagefill填充顏色
- 寫入內(nèi)容:imagestring寫簡單內(nèi)容,imagettftext寫入字體文字
- 增加干擾:imageline增加線段,imagestring增加其他符號
- 保存圖片:imagepng輸出或者保存圖片
- 簡單圖片制作
<?php
//制作簡單圖片
//1.創(chuàng)建畫布
$img = imagecreatetruecolor(200,200); //寬度和高度,像素單位,得到畫布資源
//2.輸出圖片
header('content-type:image/png');
imagepng($img); //所有g(shù)d函數(shù)都需要圖片資源
//3.銷毀資源
imagedestroy($img);
- 簡單驗(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);
- 封裝簡單驗(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é)
- 驗(yàn)證碼指的是印在圖片上的隨機(jī)字符
- 驗(yàn)證碼圖片的制作流程:畫布->背景色->隨機(jī)字符串->寫入字符串->干擾->輸出圖片->銷毀畫布
- 驗(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)追溯(防止別人盜圖商用)。
- 水印制作流程(圖片版)
- 打開原圖:imagecreatefromjpeg/png,從jpeg(基本上都是)打開原圖資源
- 打開水印圖:與原圖一樣,只是圖片通常是png
- 復(fù)制水印圖合并到原圖上:imagecopymerge
- 保存圖片:imagejpeg/png
- 關(guān)閉資源
- 實(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);
- 封裝水印圖制作函數(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é)
- 水印圖分為文字水印圖(驗(yàn)證碼)和圖片水印圖
- 水印圖的制作流程:打開原圖->打開水印圖->采樣復(fù)制合并->保存圖片->銷毀資源
- 水印圖不像驗(yàn)證碼,一般是規(guī)定位置規(guī)定水印圖樣章的
思考:在很多網(wǎng)站上,上傳圖片的時(shí)候都會有個(gè)小圖可以看的,那么是怎么實(shí)現(xiàn)的呢?
引入:其實(shí)小圖的本質(zhì)并不是用戶上傳的,而是系統(tǒng)根據(jù)系統(tǒng)需求在用戶上傳原圖的時(shí)候,制作的一個(gè)小圖。這個(gè)小圖就是縮略圖。
4. 制作縮略圖【掌握】
定義:制作縮略圖,就是將原圖放到一個(gè)固定的大小的圖片資源里,形成一張新的圖片。通常是把大圖做成小圖,因此叫做縮略圖。
- 縮略圖制作原理
- 打開原圖資源:imagecreatefromjpeg
- 創(chuàng)建縮略圖資源:imagecreatetruecolor
- 采樣復(fù)制合并:imagecopyresampled(不失真)
- 保存縮略圖資源:imagejpeg(較多)
- 銷毀資源
- 實(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);
- 縮略圖注意事項(xiàng):原圖與縮略圖比例不一樣采用全部填充滿,會導(dǎo)致縮略圖“變形”,這種時(shí)候的解決方案如下
- 求出原圖的寬高比
- 求出縮略圖的寬高比
- 比較原圖的寬高比和縮略圖的寬高比
- 原圖寬高比大于縮略圖寬高比,說明原圖太寬,應(yīng)該讓縮略圖的寬占滿,高按比例求出來
- 原圖寬高比小于縮略圖寬高比,說明原圖太高,應(yīng)該讓縮略圖的高占滿,寬按比例求出來
- 不管哪種情況,勢必會有縮略圖部分區(qū)域沒有放上內(nèi)容,這個(gè)時(shí)候縮略圖背景填充為白色(補(bǔ)白)
- 根據(jù)計(jì)算出來的實(shí)際寬高像素,將圖片居中到縮略圖中
- 制作縮略圖函數(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é)
- 縮略圖是在用戶上傳原圖的時(shí)候系統(tǒng)根據(jù)需求自動生成的
- 縮略圖要保證與原圖比例一致,就需要進(jìn)行縮略圖中圖片實(shí)際的尺寸,并進(jìn)行補(bǔ)白
