配置环境
PHP中图像处理需要GD库的支持。
在windows系统中修改php.ini文件,删除 extension=php_gd2.dll 前面的;开启图像处理支持。
centos中使用 yum install php-gd*
ubuntu系统中使用 apt-get install php7.3-gd
检测GD库是否加载
$has = extension_loaded('GD');
var_dump($has);
使用方法
PHP创建图像步骤
1.发送HTTP头信息,声明内容为图像
2.创建画布
3.创建绘图所需要的颜色
4.绘图(填充画布、画圆、画方块、画线条、画布上写字)
5.输出图像
6.释放画布资源
头信息
通过header() 函数告诉浏览器,输出的是一个图像而不是文本或HTML,这样浏览器就可以正常显示图像了。
header('Content-type:image/gif');
header('Content-type:image/jpeg');
header('Content-type:image/png');
header('Content-type:image/jpeg');
readfile('user.jpeg');
创建画布
imageCreateTrueColor(width,height)
- 传入的两个参数分别为画布的宽和高,在绘图时超出宽高的部分将不予显示,且此尺寸即为生成图片文件时的尺寸。
- 返回值为资源类型。
设置颜色
imageColorAllocate(img_resource,R,G,B)
- 颜色从属于某个图像资源而存在。
- 颜色实际上是一个整形数值。
- 颜色的后三个参数需传入值的范围是0~255
填充颜色
imageFill(img_resource,x,y,color)
- (x,y)表示从哪个点开始填充颜色的坐标
- 不填充画布的话,默认是黑色
header('Content-type:image/jpeg');
$res = imagecreatetruecolor(1000, 500);
$red = imagecolorallocate($res, 255, 0, 0);
imagefill($res, 0, 0, $red);
imagejpeg($res);
绘制矩形
绘制空心矩形
- imageRectangle(img_res,x1,y1,x2,y2,color)
header('Content-type:image/jpeg');
$res = imagecreatetruecolor(1000, 500);
$red = imagecolorallocate($res, 255, 0, 0);
$green = imagecolorallocate($res, 0, 255, 0);
imagefill($res, 0, 0, $red);
imagerectangle($res, 100, 100, 200, 200, $green);
imagejpeg($res);
绘制填充好的实心矩形
imageFilledRectangle (img_res,x1,y1,x2,y2,color)
- (x1,y1)为左上角坐标, (x2,y2)为右下角坐标
header('Content-type:image/jpeg');
$res = imagecreatetruecolor(1000, 500);
$red = imagecolorallocate($res, 255, 0, 0);
$green = imagecolorallocate($res, 0, 255, 0);
imagefill($res, 0, 0, $red);
imagefilledrectangle($res, 100, 100, 300, 300, $green);
imagejpeg($res);
绘制圆形
绘制空心圆形
- imageEllipse(img_res,x,y,w,h,color)
绘制填充好的实心圆
- imageFilledEllipse(img_res,x,y,w,h,color)
说明:
- (x,y)为圆心坐标。w为宽度,h为高度
header('Content-type:image/jpeg');
$res = imagecreatetruecolor(500, 500);
$red = imagecolorallocate($res, 255, 0, 0);
$green = imagecolorallocate($res, 0, 255, 0);
imagefill($res, 0, 0, $red);
imageellipse($res, 250, 250, 100, 100, $green);
imagejpeg($res);
绘制线条
imageLine(img_res,x1,y1,x2,y2,color)
- (x1,y1)为起始点坐标
- (x2,y2)为结束点坐标
$res = imagecreatetruecolor(500, 500);
$red = imagecolorallocate($res, 255, 0, 0);
$green = imagecolorallocate($res, 0, 255, 0);
imagefill($res, 0, 0, $red);
imageline($res, 0, 0, 499, 499, $green);
imagepng($res);
绘制像素
bool imagesetpixel ( resource x , int color )
- (x1,y1)为点坐标
header('Content-type:image/jpeg');
$res = imagecreatetruecolor(500, 500);
$red = imagecolorallocate($res, 255, 0, 0);
$green = imagecolorallocate($res, 0, 255, 0);
imagefill($res, 0, 0, $red);
for ($i = 0; $i < 600; $i++) {
imagesetpixel($res, mt_rand(0, 500), mt_rand(0, 500), $green);
}
imagepng($res);
输出图像
输出不同格式的图像用不同的方法:
- imagegif(img_resource[,filename])
- imagejpeg(img_resource[,filename])
- imagepng(img_resource[,filename])
- imagebmp(img_resource[,filename])
- 当设置第二个参数时表示储存文件,如果存在同名文件会覆盖
释放图像
imageDestroy(img_resource)
- 图像输出完毕及时释放资源,把内存空间留给更需要的程序。
输入文本
array imagettftext ( resource size , float x , int color , string text )
- 参数说明:图像资源,字体尺寸,角度,第一个字符的基本点(大概是字符的左下角),Y 坐标(字体基线的位置),颜色 ,字体文件,文本字符串(UTF-8 编码)
header('Content-type:image/png');
$res = imagecreatetruecolor(500, 500);
$red = imagecolorallocate($res, 255, 0, 0);
$green = imagecolorallocate($res, 0, 255, 0);
imagefill($res, 0, 0, $red);
$font = realpath('source.otf');
imagettftext($res, 50, 0, 0, 50, $green, $font, 'PFinal社区.com');
imagepng($res);
imagedestroy($res);
array imagettfbbox ( float angle , string text )
- 文本范围的盒子大小,可以方便控制文本输出位置
- 返回一个含有 8 个单元的数组表示了文本外框的四个角:
表头1 表头2 0 左下角 X 位置 1 左下角 Y 位置 2 右下角 X 位置 3 右下角 Y 位置 4 右上角 X 位置 5 右上角 Y 位置 6 左上角 X 位置 7 左上角 Y 位置
文字在画布右上角显示
$font = realpath('source.otf');
$text = 'PFinal社区.com';
$size = 16;
$box = imagettfbbox($size, 0, $font, 'PFinal社区.com');
$width = $box[2] - $box[0];
$height = $box[0] - $box[7];
imagettftext($res, $size, 0, 500 - $width, $height, $green, $font, 'PFinal社区.com');
文字在画布中间显示
...
imagettftext($res, $size, 0, 250 - $width / 2, 250 - $height / 2, $green, $font, 'PFinal社区.com');
...
外部图像
打开图片文件
- imageCreateFromgif(filename/url)
- imageCreateFromjpeg(filename/url)
- imageCreateFrompng(filename/url)
- imageCreateFrombmp(filename/url)
返回一个资源类型
获得信息
imagesx(img_resource)
- 取得图像宽度
imagesy(img_resource)
- 取得图像高度
getimagesize(img_file)
array getimagesize ( string $filename [, array &$imageinfo ] )
图像复制
拷贝图像的一部分
bool imagecopy ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h )
拷贝并合并图像的一部分
bool imagecopymerge ( resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h , int $pct )
图片缩放
拷贝部分图像并调整大小
bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
验证码
使用方法
# 后台code.php
include 'Captcha.php';
$code = new Captcha(100, 30, 20);
$code->make();
# 前台
验证码类
width = $width;
$this->height = $height;
$this->font = realpath('source.otf');
$this->size = $size;
}
public function make()
{
$res = imagecreatetruecolor($this->width, $this->height);
imagefill($this->res = $res, 0, 0, imagecolorallocate($res, 200, 200, 200));
$this->text();
$this->line();
$this->pix();
$this->render();
}
protected function text()
{
$text = 'abcdefghigk123456789';
for ($i = 0; $i < $this->len; $i++) {
$x = $this->width / $this->len * $i;
$box = imagettfbbox($this->size, 0, $this->font, $text[$i]);
imagettftext(
$this->res,
$this->size,
mt_rand(-20, 20),
$x,
$this->height / 2 + ($box[0] - $box[7]) / 2,
$this->textColor(),
$this->font,
strtoupper($text[$i])
);
}
}
protected function pix()
{
for ($i = 0; $i < 300; $i++) {
imagesetpixel(
$this->res,
mt_rand(0, $this->width),
mt_rand(0, $this->height),
$this->color()
);
}
}
protected function line()
{
for ($i = 0; $i < 6; $i++) {
imagesetthickness($this->res, mt_rand(1, 3));
imageline(
$this->res,
mt_rand(0, $this->width),
mt_rand(0, $this->height),
mt_rand(0, $this->width),
mt_rand(0, $this->height),
$this->color()
);
}
}
protected function color()
{
return imagecolorallocate($this->res, mt_rand(100, 200), mt_rand(100, 200), mt_rand(100, 200));
}
protected function textColor()
{
return imagecolorallocate($this->res, mt_rand(50, 150), mt_rand(50, 150), mt_rand(50, 150));
}
protected function render()
{
header('Content-type:image/png');
imagepng($this->res);
}
}
水印类
调用方式
make('sun.png', '2.png', 5);
水印类源码
water = $water;
}
//入口方法
public function make(string $image, string $filename = null, int $pos = 9)
{
$res = $this->resource($image);
$water = $this->resource($this->water);
$postion = $this->position($res, $water, $pos);
imagecopy($res, $water, $postion['x'], $postion['y'], 0, 0, imagesx($water), imagesy($water));
$this->showAction($image)($res, $filename ?: $image);
}
//获取资源对象
protected function resource($image)
{
$info = getimagesize($image);
$function = [1 => 'imagecreatefromgif', 2 => 'imagecreatefromjpeg', 3 => 'imagecreatefrompng'];
$call = $function[$info[2]];
return $call($image);
}
//根据类型输出图片
protected function showAction(string $image)
{
$info = getimagesize($image);
$function = [1 => 'imagegif', 2 => 'imagejpeg', 3 => 'imagepng'];
return $function[$info[2]];
}
//位置
protected function position($des, $res, int $pos)
{
$info = ['x' => 0, 'y' => 0];
switch ($pos) {
case 1:
break;
case 2:
$info['x'] = (imagesx($des) - imagesx($res)) / 2;
break;
case 3:
$info['x'] = (imagesx($des) - imagesx($res));
break;
case 4:
$info['y'] = (imagesy($des) - imagesy($res)) / 2;
break;
case 5:
$info['x'] = (imagesx($des) - imagesx($res)) / 2;
$info['y'] = (imagesy($des) - imagesy($res)) / 2;
break;
}
return $info;
}
}
缩略图
调用方式
include 'Resize.php';
$image = new Resize;
$image->make('sun.png', '1.jpeg', 200, 200, 3);
缩略图类源码:
resource($file);
$info = $this->size($width, $height, imagesx($image), imagesy($image), $type);
$res = imagecreatetruecolor($info[0], $info[1]);
imagecopyresampled($res, $image, 0, 0, 0, 0, $info[0], $info[1], $info[2], $info[3]);
header('Content-type:image/jpeg');
imagejpeg($res);
}
protected function size($rw, $rh, $iw, $ih, int $type)
{
switch ($type) {
case 1:
//固定宽度,高度自动
$rh = $rw / $iw * $ih;
break;
case 2:
//高度固定,宽度自动
$rw = $rh / $ih * $iw;
break;
case 3:
//固定宽度,高度裁切
$ih = $iw / $rw * $rh;
break;
default:
if (($iw / $rw) > ($ih / $rh)) {
$iw = $ih / $rh * $rh;
} else {
$ih = $iw / $rw * $rw;
}
}
return [$rw, $rh, $iw, $ih];
}
protected function resource(string $image)
{
if (!file_exists($image) || getimagesize($image) === false) {
throw new Exception("file dont exists or it's not an image file");
}
$functions = [1 => 'imagecreatefromgif', 2 => 'imagecreatefromjpeg', 3 => 'imagecreatefrompng'];
$info = getimagesize($image);
$call = $functions[$info[2]];
return $call($image);
}
}