PHP 畫圖應用生成驗證碼和柱狀圖
本篇介紹如何使用PHP常用的繪圖函數來生成驗證碼圖片和柱狀圖。
一.驗證碼
在網站中驗證碼是非常有用的,下圖就是一個含4個數字的驗證碼圖片。

簡單的驗證碼圖片主要通過在正確內容上增加一些干擾的點和線。這種方法實現起來方便容易,作為示范,本文實現了一個隨機字體(有10種字體文件),支持隨機文字顏色,有干擾點,干擾線的驗證碼類,此類可以批量在磁盤上生成驗證碼圖片并指定驗證碼由多少個數字多少個字母組成。具體功能可以參閱代碼:
//PHP生成驗證碼
// by MoreWindows( http://blog.csdn.net/MoreWindows )
class CSecurity_verify
{
private $m_image;
private $m_dir_name;
private $m_image_width;
private $m_image_height;
private $m_digit_num;
private $m_letter_num;
private $m_font_color;
const NOISE_DOT_NUM = 100; //干擾點個數
const NOISE_LINE_NUM = 40; //干擾線個數
/*
* $dir_name 保存驗證碼圖片的文件夾目錄(絕對路徑)
* $digit_num 數字個數
* $letter_num 字母個數
* $width 驗證碼圖片寬
* $height 驗證碼圖片高
*/
public function __construct($dir_name, $digit_num, $letter_num, $width = 140, $height = 40)
{
$this->m_dir_name = $dir_name;
$this->m_digit_num = $digit_num;
$this->m_letter_num = $letter_num;
$this->m_image_width = $width;
$this->m_image_height = $height;
}
/*
* 在指定目錄上生成指定條件的驗證碼圖片
* $verify_pic_num 要生成多少張驗證碼圖片
*/
public function BatchVerifyPicture($verify_pic_num)
{
while ($verify_pic_num >= 0)
{
$verify_pic_num--;
self::CreateVerifyImage();
self::DrawNoiseDot();
self::DrawNoiseLine();
$verify_text = self::GetVerifyText();
$filesize = self::DrawVerifyImage($verify_text);
if ($filesize != -1)
echo $verify_text . ".png生成成功,大小" . $filesize . "字節
";
else
echo $verify_text . ".png生成失敗
";
}
}
/*
* 創建圖片
*/
protected function CreateVerifyImage()
{
$this->m_image = imagecreatetruecolor($this->m_image_width, $this->m_image_height) or die("CreateVerifyImage failde");
$black_color = imagecolorallocate($this->m_image, 243, 251, 254);
imagefill($this->m_image, 0, 0, $black_color);//設置底色
//字體顏色
$m_font_color = imagecolorallocate($this->m_image, mt_rand(0, 120), mt_rand(0, 120), mt_rand(0, 120));
}
/*
* 生成驗證碼內容
* 驗證碼中使用的字符,01IOQ容易混淆,故不用。
*/
protected function GetVerifyText()
{
$verify_text = "";
$letter_array = "ABCDEFGHJKLMNPRSTUVWXYZ";
$digit_num = $this->m_digit_num;
$letter_num = $this->m_letter_num;
while ($digit_num--) //數字
$verify_text .= mt_rand(2, 9);
while ($letter_num--) //字母
$verify_text .= $letter_array[mt_rand(0, 22)];
return $verify_text;
}
/*
* 繪驗證碼
*/
protected function DrawVerifyImage($verify_text)
{
//字體文件
$font_file = "ttfs\\t" . mt_rand(1, 10) . ".ttf";
//
$verify_text_show = "";
for ($i = 0; $i < strlen($verify_text); $i++)
$verify_text_show .= ($verify_text[$i] . " ");
//文字的大小,角度,位置
$font_size = 20;
$font_angle = mt_rand(0, 5);
$font_pos_x = 0;
$font_pos_y = $this->m_image_height - 5;
imagettftext($this->m_image, $font_size, $font_angle, $font_pos_x, $font_pos_y, $this->m_font_color, $font_file, $verify_text_show);
$verify_image_filename = $this->m_dir_name . "\\$verify_text.png";
if (!imagepng($this->m_image, $verify_image_filename))
return -1;
imagedestroy($this->m_image);
return filesize($verify_image_filename);
}
/*
* 繪干擾點
*/
protected function DrawNoiseDot()
{
$noise_dot_color = $this->m_font_color;
for ($i = 0; $i < self::NOISE_DOT_NUM; $i++)
{
imagesetpixel($this->m_image, mt_rand(0, $this->m_image_width), mt_rand(0, $this->m_image_height), $noise_dot_color);
}
}
/*
* 繪干擾線
*/
protected function DrawNoiseLine()
{
for ($i = 0; $i < self::NOISE_LINE_NUM; $i++)
{
$noise_line_color = imagecolorallocate($this->m_image, mt_rand(50, 120), mt_rand(50, 120), mt_rand(50, 120));
imageline($this->m_image, mt_rand(0, $this->m_image_width), mt_rand(0, $this->m_image_height), mt_rand(0, $this->m_image_width), mt_rand(0, $this->m_image_height), $noise_line_color);
}
}
} 再給出使用示例,運行后可以會D盤上生成6張驗證碼圖片,代碼如下:
require_once 'CSecurity_verify.php';
$test = new CSecurity_verify("D:\\", 4, 0);
$test->BatchVerifyPicture(6); 生成的驗證碼效果如下所示:

當然還有很多特效可以加入的,如文字水波化、背景增加彩色小字母干擾等等,這些都可以有效的美化驗證碼圖片。有需要的筒子們可以深入學習下,這里就不細究了。
注 程序所使用字體文件可以從C:\Windows\Fonts中選擇,并拷貝到PHP文件所在目錄中的ttfs文件夾。
二.柱狀圖
在PHP中繪制柱狀圖可以使用bool imagefilledarc( resource $image , int $cx , int $cy , int $w , int $h , int $s , int $e , int $color , int $style )函數。此函數的說明可以參考《PHP 畫圖基礎》一文,柱狀圖原理很簡單就是先用暗色繪制多層再用亮色繪制最上層,這樣明暗對比就可以產生立體效果。具體過程可以參考下圖:

再給出一個PHP根據各數據值來生成柱狀圖的示例代碼:
//柱狀圖
// by MoreWindows( http://blog.csdn.net/MoreWindows )
$image_width = 400;
$image_height = 300;
$image = imagecreatetruecolor($image_width, $image_height);
$black_color = imagecolorallocate($image, 243, 251, 254);
imagefill($image, 0, 0, $black_color);//設置底色
//亮色
$gray_color = imagecolorallocate($image, 0xC0, 0xC0, 0xC0);
$navy_color = imagecolorallocate($image, 0x00, 0x00, 0x80);
$red_color = imagecolorallocate($image, 0xFF, 0x00, 0x00);
//暗色
$darkgray_color = imagecolorallocate($image, 0x90, 0x90, 0x90);
$darknavy_color = imagecolorallocate($image, 0x00, 0x00, 0x50);
$darkred_color = imagecolorallocate($image, 0x90, 0x00, 0x00);
//各份份量大小
$value_array = array(12.5, 8.4, 79.1);
$all_value = array_sum($value_array);
$color_array = array($gray_color, $navy_color, $red_color);
$drak_color_array = array($darkgray_color, $darknavy_color, $darkred_color);
//先用暗色繪制30層
for ($i = 80; $i > 50; $i--)
{
$angle_begin = 0;
$angle_end = 0;
foreach ($value_array as $j=>$val)
{
$angle_begin = $angle_end;
$angle_end += $val * 360 / $all_value;
imagefilledarc($image, 100, $i, 200, 100, $angle_begin, $angle_end, $drak_color_array[$j], IMG_ARC_PIE);
}
}
//最上層再用亮色繪圖,這樣就有立體效果了。
$angle_begin = 0;
$angle_end = 0;
foreach ($value_array as $j=>$val)
{
$angle_begin = $angle_end;
$angle_end += $val * 360 / $all_value;
imagefilledarc($image, 100, $i, 200, 100, $angle_begin, $angle_end, $color_array[$j], IMG_ARC_PIE);
}
// flush image
header('Content-type: image/png');
imagepng($image);
imagedestroy($image); 運行效果如下:

總體來說,PHP的繪圖功能還是方便強大的,有需要的筒子們還可以試下PHPlot來繪圖,其類庫功能強大,使用也方便。
轉載請標明出處,原文地址:http://blog.csdn.net/morewindows/article/details/7289686