PHPDay0D:图片验证码的实现

目录

0x00 图片验证码的组成

0x02 GD库的相关函数

0x03 实现验证码

0x04 实现验证码类

0x05 验证码图片不显示的几种情况


0x00 图片验证码的组成

背景图片

验证码

干扰元素:线 点

0x01 图片验证码的步骤:

  1. 创建背景图片
  2. 生成验证码
  3. 画干扰元素
  4. 输出图片

注意需要GD库

0x02 GD库的相关函数

1.resource imagecreate(int $x_size,int $y_size)

@$x_size:宽

@$y_size:高

新建一个基于调色板的图片,返回值为图片句柄

2.imgpng(图片句柄) 以png的格式输出图片

imgjpeg(图片句柄) 以jpeg的格式输出图片

注意:在输出图片前需要加上

header("Content-type:image/jpeg");

表示以image/jpeg的格式解析图片

3.int imagecolorallocate(resource $image,int red,int$green,int blue);

@为一幅图像分配颜色;

@返回值为对应颜色的int值;可以用于imagettftext()的参数

4.imagettftext(resource $image,float $size,float $angle,int $x,int $y,int $color,string $frontfile,string $text)

用truetype字体向图像写入文本

$angle 字体倾斜度

$x $y 字体的位置

$fontfile 是字体文件(字体文件的路径) 准备好ttf文件,建议放在同源文件夹内

$text 要绘制的字。

注意:

mt_rand()和rand()效果相同,但是mt_rand()的效率更高一些

5.bool  imageline(resource $image,int $x1,int $y1,int $x2,int $y2,int color);

@画线

@x1,y1:起点坐标

@x2,y2:终点坐标

6.bool imagesetpixel(resource $image,int $x,int $y,int $color)

@画点

7.bool imagedestroy(resource $image)

@销毁图片资源

@销毁图像资源

0x03 实现验证码

<?php
class Color{
	public $red;
	public $green;
	public $blue;
	public function __construct($r,$g,$b){
		$this->red = $r;
		$this->green = $g;
		$this->blue = $b;
	}
};
$color_array = [];
array_push($color_array,new Color(0,0,139));
array_push($color_array,new Color(139,0,139));
array_push($color_array,new Color(139,0,0));
array_push($color_array,new Color(205,0,0));
$width = 200;
$height = 50;
$img = imagecreate($width,$height);
imagecolorallocate($img,100,149,237);
$str = 'abcdefghjklmnpqrstuvwxyz23456789ABCDEFGHJKMNPQRSTUVWXYZ';
$check_str = '';
$len = 4;
for($i=0;$i<$len;$i++){
	$key =mt_rand(0,strlen($str)-1);
	$check_str.=$str[$key];

}
for($i=0;$i<$len;$i++){
	$font_size = mt_rand(15,17);
	$x =$i * ($width/$len) + $font_size/2;
	$y =mt_rand($font_size,$height-$font_size);
	$angle = mt_rand(-50,50);
	$color = $color_array[mt_rand(0,3)];
	$font_color = imagecolorallocate($img,$color->red,$color->green,$color->blue);
	imagettftext($img,$font_size,$angle,$x,$y,$font_color,'code2.ttf',$check_str[$i]);
}
for($i=0;$i<100;$i++){
	$x_pix = mt_rand(0,$width);
	$y_pix = mt_rand(0,$height);
	$dot_color = imagecolorallocate($img,mt_rand(100,255),mt_rand(100,255),mt_rand(100,255));
	imagesetpixel($img,$x_pix,$y_pix,$dot_color);

}
$times =5;
for($i=0;$i<$times;$i++){
	$x_beg_line = mt_rand(0,$width/$len);
	$x_end_line = mt_rand($width - $width/$len ,$width);
	$y_beg_line = mt_rand(0,$height);
	$y_end_line = mt_rand(0,$height);
	$line_color = imagecolorallocate($img,mt_rand(100,255),mt_rand(100,255),mt_rand(100,255));
	imageline($img,$x_beg_line,$y_beg_line,$x_end_line,$y_end_line,$line_color);
}
header('Content-type:image/jpeg');
imagejpeg($img);
imagedestroy($img);
?>

0x04 实现验证码类

<?php

class CheckCode{
	private $width;
	private $height;
	private $hImg;
	private $str;
	private $code;
	private $code_len;
	public function __construct($width,$height,$str,$code_len){
		$this->width = $width;
		$this->height = $height;
		$this->hImg = imagecreate($this->width,$this->height);
		$this->str = $str;
		$this->code_len = $code_len;
	}


	public function draw(){
		$this->draw_bk();
		$this->set_code();
		$this->set_session();
		$this->draw_code();
		$this->draw_salt();
		ob_end_clean();
		header("Content-type:image/jpeg");
		imagejpeg($this->hImg);
		imagedestroy($this->hImg);
	
	}
	private function draw_bk(){
		imagecolorallocate($this->hImg,0,0,0);
	}
	private function set_code(){
		for($i=0;$i<$this->code_len;$i++){
			$this->code .= $this->str[mt_rand(0,strlen($this->str)-1)];
		}
	}
	private function set_session(){
		session_start();
		$_SESSION['code'] = strtolower($this->code);
	}
	private function draw_code(){
		for($i=0;$i<$this->code_len;$i++){
			$size = 18;
			$x = $i * ($this->width / $this->code_len) + $size;
			$y = mt_rand($size,$this->height-$size);
			$color = imagecolorallocate($this->hImg,0,255,0);
			$angle = mt_rand(-25,25);
			imagettftext($this->hImg,$size,$angle,$x,$y,$color,'code2.ttf',$this->code[$i]);
		}
	}
	private function draw_salt(){
		for($i=0;$i<5;$i++){
			$bx = 0;
			$by = mt_rand(0,$this->height);
			$ex = $this->width;
			$ey = mt_rand(0,$this->height);
			$lcolor = imagecolorallocate($this->hImg,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
			imageline($this->hImg,$bx,$by,$ex,$ey,$lcolor);
		}
		for($i=0;$i<100;$i++){
			$x = mt_rand(0,$this->width);
			$y = mt_rand(0,$this->height);
			$pcolor = imagecolorallocate($this->hImg,mt_rand(0,255),mt_rand(0,255),mt_rand(0,255));
			imagesetpixel($this->hImg,$x,$y,$pcolor);
		}
	}

}
$str = 'abcdefghjkmnpqrstuvwxyz23456789ABCDEFGHJKMNPQRSTUVWXYZ';
$cc = new CheckCode(200,50,$str,4);
$cc->draw();
?>

0x05 验证码图片不显示的几种情况

1.你的验证码之前显示正常,突然不显示了 >>> 可能是GD库有问题。在php.ini中打开GD库

2.文件编码格式不对,文件编码格式最好是utf-8,不要是utf-8 BOM 或者是其他编码

3.图片输出前可能有输出内容

例如:

<?php
    echo 'hello world';
    header('Content-type:image/jpeg');
    imagejpeg($hImg);

?>

这样做其实相当于在图片的二进制文件的开头加上了hello world。

解决方案

加上ob_end_clean();清空缓存区

<?php
    echo 'hello world';
    ob_end_clean();
    header('Content-type:image/jpeg');
    imagejpeg($hImg);

?>
发布了156 篇原创文章 · 获赞 19 · 访问量 8943

猜你喜欢

转载自blog.csdn.net/weixin_43415644/article/details/104022163