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(color,==realpath(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 點擊驗證碼刷新
<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)中使用數據
- 在產生驗證碼的captcha.php文件中將驗證碼字符串寫到$_SESSION中
//將隨機生成的驗證碼寫入session
session_start();
$_SESSION['code']=$code;
- 在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;
}