准备:
首先,我们必须有一个背景图像和一个徽标图像。 另外,还必须有一个类库。 我就不谈这么多了。 我在百度上搜了很多。
准备好这些内容之后,我们就开始编写代码了。
生成二维码:
首先我们需要使用类库生成原始二维码:
我们来看几个参数:
我们一般使用png()方法来生成二维码。 我们不会在这里讨论其他格式。
png() 方法有 6 个参数:
第一个:$text生成的二维码中包含的信息。
第二个:$ 是否默认不生成文件,这是生成二维码的路径
第三个:$level生成的二维码的容错率,即可以识别覆盖的区域,分别为L(,7%)、M(,15%)、Q(,25%)、H ( , 30%);
第四个:$size,控制生成图像的大小,默认为4
第五:$,控制生成二维码的空白区域大小
第六:$,保存二维码图片并显示,$必须传递图片路径。
了解了这些参数后,我们就可以进行简单的设置:
$text = "这只是一个测试二维码!";
$QRDir = "./base.png"; //生成的图片路径
$errorCorrectionLevel = 'H';//容错率
$matrixPointSize = 10;//生成的图片的大小
$margin = 2;
至于第六个参数,我们就不设置了。 在实际项目中,我们不需要将图片打印出来。 该图片通常设置为下载。 我这里就不详细说了。
$qrCode = new QRcode();
$qrCode->png($text, $QRDir, $errorCorrectionLevel, $matrixPointSize, $margin);
通过以上操作,我们生成了一个二维码,并将二维码的内容保存在base.png图片中。
如果简单的获取一个二维码,那么上面的操作就达到目的了。 但只有一个二维码有点难看。 在实际项目中,这个二维码需要进行美化,添加一些我们需要的背景和标志。 接下来我们将对二维码进行进一步的处理,让二维码更加美观。
我的实际项目中有两种情况,一种是生成不带logo的二维码,一种是生成带logo的二维码。
我们先说一下无logo的二维码的生成:
因为我们生成的二维码可能无法100%放入我们预先设置的背景图中:(当然,你也可以在制作背景图时测量尺寸,只需将二维码放入背景图中即可) ,这里需要解释一下什么是100%放入背景图,即生成的二维码和背景中预留的显示二维码的空间可以刚好靠在一起,因为背景有时会变化的,大小生成的二维码是固定的,无法满足我们的需求。
当遇到上述变化的背景图像时,需要对生成的二维码进行处理,对生成的二维码进行放大或缩小。
需要简单介绍一下几个图像处理函数:
imagecreatefromgif():创建一块画布,并从 GIF 文件或 URL 地址载入一副图像
imagecreatefromjpeg():创建一块画布,并从 JPEG 文件或 URL 地址载入一副图像
imagecreatefrompng():创建一块画布,并从 PNG 文件或 URL 地址载入一副图像
imagecreatefromwbmp():创建一块画布,并从 WBMP 文件或 URL 地址载入一副图像
imagecreatefromstring():创建一块画布,并从字符串中的图像流新建一副图像
使用上述函数读取生成的二维码图像,并获取二维码的高度和宽度。
$QRImageInfo = imagecreatefromspng($QRDir);
$QR_width = imagesx($QRImageInfo);
$QR_height = imagesy($QRImageInfo);
然后创建一张我们需要大小的图片:
使用()方法创建图片资源,并使用()方法设置图片背景色
$width = 539;
$height = 539;
$newImage = imagecreatetruecolor($width,$height);//创建一个图像资源
$newImage_white = imagecolorallocate($newImage, 255,255,255);//给创建好的图像资源设置白色背景
imagefill($newImage, 0, 0, $newImage_white);//填充$newImage
接下来,使用 () 函数将二维码图像缩放到新创建的图像:
()函数有10个参数:
1、新要放置的图片资源(目标图片资源)
2、待缩放的图片资源(原图片资源)
3.目标图像起始x坐标dst_x
4.目标图像的起始y坐标dst_y
5.原图的起始x坐标src_x
6.原图的起始y坐标src_y
7.目标图像dst_w的宽度
8.目标图像的高度dst_h
9.原图src_w的宽度
10.原图src_h的高度
根据上面的参数,我们可以将二维码图像放入到新创建的图像中:
imagecopyresized($newImage, $QRImageInfo,0, 0, 0, 0, 539, 539, $QR_width, $QR_height);
生成的 $ 是缩放后的 QR 码。
下一步是将缩放后的二维码放在已经设计好的底图之上。
这个功能和上面的效果是一样的,但是这个功能的效果更好。 参数也相同。
$backgroundDir = "./background.png";//事先准备好的背景图片
$backgroundImg = imagecreatefromspng($backgroundDir);
imagecopyresampled($backgroundImg, $newImage, 203, 330, 0, 0, 539, 539, 539, 539);
最后保存合并后的图片:
$resultPngPic = "./resultPngPicWithoutLogo.png";//设置最后生成图像的路径
imagepng($backgroundImg,$resultPngPic);
imagedestroy($newImage);//销毁中间创建的$newImage资源
这样就会在当前目录下得到一张名为ogo.png的图片,图片的内容就是我们想要的二维码图片。
下一步是生成带有 Logo 的二维码:
生成带logo的二维码的思路和上面不带logo的二维码的思路是一样的,都是将我们需要的图像进行缩放,然后与二维码图像合并,形成二维带有徽标的代码。 码,然后将此二维码放入背景图片中。 这里的操作和上面完全一样。 这里我们重点介绍一下如何实现图片的圆角设置,如下图:
在生成带logo的二维码时,我们也希望logo是圆角的,就像微信、支付宝的二维码一样。
首先打开准备好的logo图片:
$logoDir = "./logo.png";
$resource = imagecreatefrompng($logoDir);
$image_width = imagesx($resource);
$image_height = imagesy($resource);
创建一个与当前图像大小相同的画布:
$targetImg = imagecreatetruecolor($logo_width, $logo_height);
imagesavealpha($targetImg, true);//保留图片的透明通道
$targetImgBackground = imagecolorallocatealpha($targetImg, 255, 255, 255, 127);//将目标图片设置成透明背景
imagefill($targetImg, 0, 0, $targetImgBackground);//填充透明背景
下一步是将徽标图像绘制到目标图像上:
这里有两种方法,第一种比较灵活,但是效率低下:就是判断每个像素是否落入我们想要的范围内,如果落入我们想要的范围内,就把这个像素画到画布上,重复这个过程直到遍历完所有像素。 这样我们就相当于裁剪了一张新的图片。 这种方法可以裁剪任何图片,只要你能很好地判断像素即可。 但缺点是效率太低。 所有的像素都需要遍历一次,画布需要修改多次才能得到最终的图片。 如果是专业需要,牺牲一些性能也是可以接受的。 但我们只需要一个带有圆角的简单图像。 这样的要求根本不需要遍历所有像素。
第二种方法是我们可以创建一个小正方形,并将这个小规则形状切割成扇形。 这样,剪下来的扇形就会与原图结合起来,形成圆角的图片。 但这里有一个问题。 得到的圆角图像只是形式上是圆角的,圆角外面是一圈背景,并不透明。
我们先看第二种方法:
$r = $radius; //圆角半径
function litter_corner($radius){
$img = imagecreatetruecolor($radius, $radius);
imagesavealpha($img, true);
$bgcolor = imagecolorallocatealpha($img, 0, 0, 0,127);
$fgcolor = imagecolorallocate($img, 0, 0, 0);
imagefill($img, 0, 0, $bgcolor);
imagefilledarc($img, $radius, $radius, $radius*2, $radius*2, 180, 270, $fgcolor, IMG_ARC_PIE);
imagecolortransparent($img, $fgcolor);
return $img;
}
// lt(左上角)
$lt_corner = litter_corner($radius);
imagecopymerge($resource, $lt_corner, 0, 0, 0, 0, $radius, $radius, 100);
// lb(左下角)
$lb_corner = imagerotate($lt_corner, 90, 0);
imagecopymerge($resource, $lb_corner, 0, $image_height - $radius, 0, 0, $radius, $radius, 100);
// rb(右上角)
$rb_corner = imagerotate($lt_corner, 180, 0);
imagecopymerge($resource, $rb_corner, $image_width - $radius, $image_height - $radius, 0, 0, $radius, $radius, 100);
// rt(右下角)
$rt_corner = imagerotate($lt_corner, 270, 0);
imagecopymerge($resource, $rt_corner, $image_width - $radius, 0, 0, 0, $radius, $radius, 100);
$image = "logoFinal.png";
imagepng($resource,$image);
这样就得到了带有背景色的圆形标志,但是这种方法并没有得到透明图像。 后续研究一下是否可以得到透明的图片,达到想要的效果。
第二种方法是获取背景透明的圆角标志图片,代码如下:(这段代码是从网上找到的,基本思想是通过计算像素点的位置来判断是否显示,并保持图像通过质点得到的最终图)
function radius_img($imgpath, $radius = 15) {
$ext = pathinfo($imgpath);
$src_img = null;
switch ($ext['extension']) {
case 'jpg':
$src_img = imagecreatefromjpeg($imgpath);
break;
case 'png':
$src_img = imagecreatefrompng($imgpath);
break;
}
$wh = getimagesize($imgpath);
$w = $wh[0];
$h = $wh[1];
// $radius = $radius == 0 ? (min($w, $h) / 2) : $radius;
$img = imagecreatetruecolor($w, $h);
//这一句一定要有
imagesavealpha($img, true);
//拾取一个完全透明的颜色,最后一个参数127为全透明
$bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
imagefill($img, 0, 0, $bg);
$r = $radius; //圆 角半径
for ($x = 0; $x < $w; $x++) {
for ($y = 0; $y < $h; $y++) {
$rgbColor = imagecolorat($src_img, $x, $y);
if (($x >= $radius && $x <= ($w - $radius)) || ($y >= $radius && $y <= ($h - $radius))) {
//不在四角的范围内,直接画
imagesetpixel($img, $x, $y, $rgbColor);
} else {
//在四角的范围内选择画
//上左
$y_x = $r; //圆心X坐标
$y_y = $r; //圆心Y坐标
if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
imagesetpixel($img, $x, $y, $rgbColor);
}
//上右
$y_x = $w - $r; //圆心X坐标
$y_y = $r; //圆心Y坐标
if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
imagesetpixel($img, $x, $y, $rgbColor);
}
//下左
$y_x = $r; //圆心X坐标
$y_y = $h - $r; //圆心Y坐标
if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
imagesetpixel($img, $x, $y, $rgbColor);
}
//下右
$y_x = $w - $r; //圆心X坐标
$y_y = $h - $r; //圆心Y坐标
if (((($x - $y_x) * ($x - $y_x) + ($y - $y_y) * ($y - $y_y)) <= ($r * $r))) {
imagesetpixel($img, $x, $y, $rgbColor);
}
}
}
}
return $img;
}
$final_logo = radius_img($resource);
imagepng($final_logo, "logoFinal.png");
通过调用这个函数,我们可以很容易的得到一个透明的圆角标志,其实很简单,但是相对来说,比上面的合成图片要麻烦一些。
最后就是将修改后的logo图片粘贴到二维码中间。 这可能涉及到图片的大小,可以通过缩放之前的图片得到一个理想的大小。
合成代码如下:
$QR = imagecreatefrompng("qr.png");//这里qr.png是二维码的图片
$logo = imagecreatefrompng("logoFinal.png");//圆角二维码logo
$QR_width = imagesx($QR);//二维码图片宽度
$QR_height = imagesy($QR);//二维码图片高度
$logo_width = imagesx($logo);//logo图片宽度
$logo_height = imagesy($logo);//logo图片高度
$logo_qr_width = $QR_width / 5;
$scale = $logo_width/$logo_qr_width;
$logo_qr_height = $logo_height/$scale;
$from_width = ($QR_width - $logo_qr_width) / 2;
//重新组合图片并调整大小
imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
$QRHasLogo = "QRHasLogo.png";//最终得到的带有logo的二维码
imagepng($QR, $QRHasLogo);
这样你就会得到一张名为.png的图片,然后把这张图片粘贴到背景上就大功告成了。
最后一步和上面没有标志的二维码一样,所以不需要设置。 最终结果如下:
以上内容希望对大家有所帮助。 如有需要,可以添加下方二维码进群交流,学习新技术。