PHP图片处理技术的应用

之前碰到一个项目里,用到了图片处理技术。类似于下面这个图一样

图片分为3个部分组成,背景图,二维码图片,二维码图片下面的文字。其中,二维码图片以及文字是动态生成的,不一样的活动,二维码图片及文字描述都是不一样的。

如何完成该需求,我们需要用php的图片处理技术来实现。

基础知识

首先我们需要安装php的扩展GD库。有了他之后,才能继续进行下面的步骤。下面主要以代码为主,函数的具体用法亲们自行查阅文档。

创建画布

<?php

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

// 创建一个100*100的画布
$im = imagecreatetruecolor(100, 100);
// 生成png图片
imagepng($im);

给画布设置颜色

<?php

header("Content-type:image/png");
// 创建一个100*100的画布
$im = imagecreatetruecolor(100, 100);
// 设置红包
$color = imagecolorallocate($im, 255, 0, 0);
// 填充画布
imagefill($im, 0, 0, $color);
// 生成图片
imagepng($im);
// 销毁资源
imagedestroy($im);

改代码会生成一个100*100的红色背景图

绘制图像

绘制点和线

<?php
$imgHandler = imagecreatetruecolor(100,100);

// 填充背景
$bgColor = imagecolorallocate($imgHandler, 200, 30, 40);
imagefill($imgHandler,0, 0, $bgColor);


// 绘制点
for ($i = 0; $i < 100; $i++) {
   $pointColor = imagecolorallocate($imgHandler, rand(0,200), rand(0,200), rand(0,200));
   imagesetpixel($imgHandler, rand(0, 100), rand(0, 100), $pointColor);
}

// 绘制线
for ($i = 0; $i < 10; $i++) {
   $lineColor = imagecolorallocate($imgHandler, rand(100, 225), rand(100, 225), rand(0, 50));
   imageline($imgHandler,
       rand(0, 100),
       rand(0, 100),
       rand(0, 100),
       rand(0, 100), $lineColor);
}

header("Content-Type:image/png");
imagepng($imgHandler);
imagedestroy($imgHandler);

绘制矩形

<?php

$imgHandler = imagecreatetruecolor(100,100);

// 填充背景
$bgColor = imagecolorallocate($imgHandler, 200, 30, 40);
imagefill($imgHandler,0, 0, $bgColor);

// 绘制矩形边框
$borderCol = imagecolorallocate($imgHandler, 23, 32, 200);
imagerectangle($imgHandler, 0, 0, 99, 99, $borderCol);


header("Content-Type:image/png");
imagepng($imgHandler);
imagedestroy($imgHandler);

绘制文字

绘制普通文字

函数:imagestring()

<?php

/**绘制文字**/

$imgHandler = imagecreatetruecolor(100,100);

// 绘制矩形并填充
$borderCol = imagecolorallocate($imgHandler, 23, 32, 200);
imagefilledrectangle($imgHandler, 0, 0, 99, 99, $borderCol);

// 绘制水平方向文字
$strColor = imagecolorallocate($imgHandler, mt_rand(0,100), mt_rand(0, 100), mt_rand(0, 100));
imagestring($imgHandler, 5,1, 45, 'hello world', $strColor);

// 垂直方向文字
imagestringUp($imgHandler, 5,45, 99, 'hello world', $strColor);

header("Content-Type:image/png");
imagepng($imgHandler);
imagedestroy($imgHandler);

使用字体库绘制文字

使用imagestring来绘制文字,非常简单。但有几个缺陷。首先:它不能绘制中文,另外,使用imagestring绘制出的文字不会太大。

这里我们使用imagettftext来绘制文字,imagettftext除了能设置字体大小外,还可以给字体设置倾斜角度。

使用前,我们需要找一些ttf格式的字体。在windows系统下的C:\Windows\Fonts目录,有许多字体。

<?php

/* 使用imagettftext向图像正中写文字 */

$im = imagecreatetruecolor(300, 300);
$bgColor = imagecolorallocate($im, 222,222,222);
imagefill($im,0, 0, $bgColor);

$size = 30;
$angle = 0;
$font = 'D:\wwwroot\stdphp\img\font/msyhbd.ttf';
$text = '大圣到此一游';



//获取文字信息
$info = imagettfbbox($size, $angle, $font, $text);
$minx = min($info[0], $info[2], $info[4], $info[6]);
$maxx = max($info[0], $info[2], $info[4], $info[6]);
$miny = min($info[1], $info[3], $info[5], $info[7]);
$maxy = max($info[1], $info[3], $info[5], $info[7]);

///* 计算文字初始坐标和尺寸 */
$x = $minx;
$y = abs($miny);
$w = $maxx - $minx;
$h = $maxy - $miny;


/* 随机文字颜色 */
$textColor = imagecolorallocate($im, mt_rand(0,150), mt_rand(0,150), mt_rand(0,150));

imagettftext($im, $size, $angle, (300 - $w) / 2 + $x, (300 - $h) / 2 + $y, $textColor, $font, $text);

header("Content-type:image/png");
imagepng($im);
imagedestroy($im);

绘制的图片效果如下:

图片背景管理

之前我们学的创建画布都是从一个空白开始,然后给他填充颜色、绘制点、文字之类的。现在我们可以直接从已有的图片加载作为背景。常用的有几个函数:

imagecreatefrompng()、imagecreatefromjpeg()、imagecreatefromgif()。他们表示加载对应的图片格式。

另外我们再学一个函数,getimagesize(),返回一个具有四个单元的数组。索引 0 包含图像宽度的像素值,索引 1 包含图像高度的像素值。索引 2 是图像类型的标记:1 = GIF,2 = JPG,3 = PNG,……

<?php

/**
* 向不同的格式的图片中间画一个字符
*/
function image($imgfile, $string)
{
   list($width, $height, $type) = getimagesize($imgfile);
   $types = ['1' => 'git', '2' => 'jpeg', '3' => 'png'];
   $createFunc = 'imagecreatefrom' . $types[$type];
   $im = $createFunc($imgfile);
   $textColor = imagecolorallocate($im, 255, 0, 0);

   $x = ($width - imagefontwidth(5) * strlen($string)) / 2;
   $y = ($height - imagefontheight(5)) / 2;
   imagestring($im, 5, $x, $y, $string, $textColor);

   header("Content-type:image/".$types[$type]);
   $output = 'image'.$types[$type];
   $output($im);
   imagedestroy($im);
}

//image('timg.jpg', 'jpg');
image('1.png', 'png');

实战

通过之前3篇文章讲述了php处理图片,现在我们再次回到刚开始的那个问题。

图片分为3个部分组成,背景图,二维码图片,二维码图片下面的文字。其中,二维码图片以及文字是动态生成的,不一样的活动,二维码图片及文字描述都是不一样的。

加载背景图片

我们首先准备好一张背景图片,并加载

<?php

// 加载背景图片

$im = imagecreatefrompng('./demo.png');

header("content-type:image/png");
imagepng($im);
imagedestroy($im);

绘制文字

<?php

// 加载背景图片

$im = imagecreatefrompng('./demo.png');

// 绘制文字
$fontColor = imagecolorallocate($im, 255, 255, 255);
$font = 'C:\Users\admin\Desktop\code\demo\img/simhei.ttf';
imagettftext($im, 40, 0, 700, 400, $fontColor, $font, '我们是祖国的未来');
imagettftext($im, 40, 0, 700, 480, $fontColor, $font, '未来为祖国做贡献');

header("content-type:image/png");
imagepng($im);
imagedestroy($im);
img

加载二维码图片

一般都是通过qrcode类来生成二维码图片。这里我们就不去引入qrcode类的,直接找一个二维码图片来替代。

<?php

// 加载背景图片
$im = imagecreatefrompng('./demo.png');

// 绘制文字
$fontColor = imagecolorallocate($im, 255, 255, 255);
$font = 'C:\Users\admin\Desktop\code\demo\img/simhei.ttf';
imagettftext($im, 40, 0, 700, 400, $fontColor, $font, '我们是祖国的未来');
imagettftext($im, 40, 0, 700, 480, $fontColor, $font, '未来为祖国做贡献');

// 加载二维码图片到背景图上
$qrim = imagecreatefrompng('./qrcode.png');
list($w, $h) = getimagesize('./qrcode.png');
imagecopyresampled($im, $qrim, 160, 1800, 0, 0, $w, $h, $w, $h);

header("content-type:image/png");
imagepng($im);
imagedestroy($im);