PHP教程:如何创建带圆角Logo的二维码 - 使用qr-code库实现自定义圆角效果
本篇介绍的是php如何创建一个带圆角logo的二维码。

前言
目前有很多二维码生成的库。我使用的是 qr-code 这个库。它里面具备生成带 logo 的二维码的功能。不过美中不足的是,该库中的 logo 不能设置圆角。所以我就自己对代码进行了修改来实现这一功能。
下载名为“qr-code”的库,将其引入到项目中,“qr-code”的目录结构具体如下:
image.png
我对 PngWriter.php 文件进行了修改,此文件用于生成 png 格式的二维码,并且其中包含了 logo 的添加功能。我们可以找到 addLogo 这个方法,然后添加如下代码:
// 1: 白底
if ($imgBorderType == '1') {
$px = 4;
$logoImage 由 this 的 addBorder 方法进行处理,传入了 $logoImage 、$logoWidth 、$logoHeight 、$logoSourceWidth 、$logoSourceHeight 和 $px 这些参数。
$logoSourceWidth 等于 $logoWidth 加上 $px 乘以 2 。
$logoSourceHeight 等于 $logoHeight 加上 $px 乘以 2 ;$logoSourceHeight 是由 $logoHeight 与 $px 乘以 2 的和构成的 ;$logoSourceHeight 的值为 $logoHeight 加上 $px 乘以 2 的结果 。
$logoWidth 等于 $logoWidth 加上 $px 乘以 2 ;$logoWidth 先加上 $px 乘以 2 ;$logoWidth 是由原来的自身加上 $px 乘以 2 得到的 ;$logoWidth 加上了 $px 乘以 2 之后的结果 ;$logoWidth 加上了 $px 乘以 2 而发生了变化 ;$logoWidth 加上了 $px 乘以 2 从而有了新的值 ;$logoWidth 经过加上 $px 乘以 2 的操作后 ;$logoWidth 因为加上了 $px 乘以 2 而改变 ;$logoWidth 由于加上了 $px 乘以 2 而产生了新的状态 ;$logoWidth 加上 $px 乘以 2 后其值发生了改变 ;$logoWidth 加上 $px 乘以 2 后得到了新的数值 ;$logoWidth 加上 $px 乘以 2 后就有了新的情况 ;$logoWidth 加上 $px 乘以 2 后便有了新的模样 ;$logoWidth 加上 $px 乘以 2 后就呈现出了新的状态 ;$logoWidth 加上 $px 乘以 2 后就有了新的表现 ;$logoWidth 加上 $px 乘以 2 后就有了新的结果 ;$logoWidth 加上 $px 乘以 2 后就有了新的变化 ;$logoWidth 加上 $px 乘以 2 后就有了新的情况和数值 ;$logoWidth 加上 $px 乘以 2 后就有了新的状态和数值 ;$logoWidth 加上 $px 乘以 2 后就有了新的表现和数值 ;$logoWidth 加上 $px 乘以 2 后就有了新的结果和数值 ;$logoWidth 加上 $px 乘以 2 后就有了新的变化和数值 ;$logoWidth 加上 $px 乘以 2 后就有了新的情况和状态 ;$logoWidth 加上 $px 乘以 2 后就有了新的表现和状态 ;$logoWidth 加上 $px 乘以 2 后就有了新的结果和状态 ;$logoWidth 加上 $px 乘以 2 后就有了新的变化和状态 。
$logoHeight 加上 $px 乘以 2 的结果等于 $logoHeight 本身。$logoHeight 原本的值加上 $px 乘以 2 之后,$logoHeight 的值发生了变化。$logoHeight 先保持原有的值,然后加上 $px 乘以 2 这个增量,最终得到了新的 $logoHeight 值。
}
// 2: 圆角
如果 $imgBorderType 等于 '2' ,那么就执行以下操作;如果 $imgBorderType 等于 '2' ,则进行相应处理;当 $imgBorderType 为 '2' 时,就会有相应情况发生
$radius 等于将 imagesx($sourceImage) 乘以 0.3 再乘以 0.2 后取整的值。
$logoImage 被添加了边框,边框的宽度为 $logoWidth,高度为 $logoHeight,原始 logo 的宽度为 $logoSourceWidth,高度为 $logoSourceHeight,最终得到的是 $logoImage
$logoSourceWidth 的值等于 $logoWidth 。
$logoSourceHeight 的值等于 $logoHeight 。
$logoImage 被进行了添加半径的操作,操作对象为$logoImage、$logoWidth、$logoHeight 和$radius,操作结果为$logoImage 。
}
// 3: 圆角白底
如果 $imgBorderType 等于 '3',那么就执行以下操作;如果 $imgBorderType 为 '3' 的话,就进行相应处理;倘若 $imgBorderType 是 '3',则执行相关步骤。
$radius = intval(imagesx($sourceImage) * 0.3 * 0.2);
$logoImage = $this->addBorder($logoImage, $logoWidth, $logoHeight, $logoSourceWidth, $logoSourceHeight);
$logoSourceWidth = $logoWidth;
$logoSourceHeight = $logoHeight;
$logoImage = $this->addRadius($logoImage, $logoWidth, $logoHeight, $radius);
$px = 4;
$logoImage = $this->addBorder($logoImage, $logoWidth, $logoHeight, $logoSourceWidth, $logoSourceHeight, $px);
$logoSourceWidth = $logoWidth + $px * 2;
$logoSourceHeight = $logoHeight + $px * 2;
$logoWidth = $logoWidth + $px * 2;
$logoHeight = $logoHeight + $px * 2;
$logoImage 等于通过调用$this 的 addRadius 方法,将$logoImage、$logoWidth、$logoHeight 以及$radius 与$px 相加的结果作为参数传入该方法后得到的返回值。
}
addBorder是添加白色边框方法:
函数 addBorder 接收多个参数,包括 $img、$imgWidth、$imgHeight、$imgSourceWidth、$imgSourceHeight 和 $px(默认为 0)。这个函数用于给图片添加边框。它会根据传入的参数来确定图片的尺寸和边框的宽度等信息,以实现给图片添加边框的功能。
创建一个真彩色图像,其宽度为($imgWidth + $px * 2),高度为($imgHeight + $px * 2),并将其赋值给变量 $im 。
if (!is_resource($im)) {
生成图像时出现异常,原因是无法生成图像,建议检查你的 GD 安装情况。具体异常信息为:抛出了一个 GenerateImageException 异常,提示无法生成图像,需检查 GD 安装。
}
在 $im 中分配颜色,该颜色的 RGB 值分别为 255、255、255,分配后的颜色被存储在 $color 中。
imagefill($im, 0, 0, $color);
调用 imageColorTransparent 函数,将参数 $im 和 $color 传入该函数中
使用 imagecopyresampled 函数,将 $im 复制到 $img 中,起始坐标为 intval($px) 和 intval($px),目标图像的尺寸为 $imgWidth 和 $imgHeight,源图像的尺寸为 $imgSourceWidth 和 $imgSourceHeight。
imagedestroy($img);
return $im;
}
addRadius是设置圆角方法:
该函数用于给图像添加半径。它接受四个参数,分别是要添加半径的图像 $img、图像的宽度 $imgWidth、图像的高度 $imgHeight,以及可选的半径值 $radius,默认半径值为 20。
创建一个真彩色图像,其宽度为 $imgWidth,高度为 $imgHeight,将其赋值给变量 $im。
//这一句一定要有
imagesavealpha($im, true);
在图像中分配 Alpha 通道的颜色,将白色(RGB 值为 255, 255, 255)与 127 的透明度相结合,得到的颜色赋值给变量 $bg 。
imagefill($im, 0, 0, $bg);
$widthX 等于 $imgWidth 减去 $radius 乘以 2 。
$heightY 等于 $imgHeight 减去 $radius 乘以 2 ;$heightY 是通过用 $imgHeight 减去 $radius 乘以 2 得到的 ;$imgHeight 减去 $radius 乘以 2 的结果是 $heightY 。
$limitX = $radius;
$limitY = $radius;
if ($widthX > 0) {
使用 imagecopyresampled 函数,将 $im 复制到 $img 中,起始坐标为 intval($radius) 和 intval(0),目标尺寸为 $widthX 和 $imgHeight,源尺寸也为 $widthX 和 $imgHeight 。
if ($heightY > 0) {
使用 imagecopyresampled 函数将 $im 复制到 $img 中,起始坐标为 (0, $radius),目标坐标也为 (0, $radius),宽度和高度均为 $radius 和 $heightY 。
使用 imagecopyresampled 函数,将 $im 复制到 $img 中,起始位置为 intval($imgWidth - $radius) 和 intval($radius),复制的宽度为 $radius,高度为 $heightY,起始复制位置为 intval($imgWidth - $radius) 和 intval($radius),复制的宽度为 $radius,高度为 $heightY。
}
else {
$limitY = $imgHeight / 2;
}
}
else {
$limitX = $imgWidth / 2;
if ($heightY > 0) {
使用 imagecopyresampled 函数,将 $img 复制到 $im 中,起始坐标为 intval(0) 和 intval($radius),目标坐标也为 intval(0) 和 intval($radius),复制的宽度为 $imgWidth,高度为 $heightY,复制的目标高度也为 $heightY
}
else {
$limitY = $imgHeight / 2;
}
}
// 左上
for ($x = 0; $x < $limitX; $x++) {
for ($y = 0; $y < $limitY; $y++) {
$y_x = $radius; //圆心X坐标
$y_y = $radius; //圆心Y坐标
$this->设置半径($img,$im,$x,$y,$y_x,$y_y,$radius);
}
}
// 右上
从 $imgWidth 减去 $limitX 得到 $x,然后当 $x 大于等于 0 时,执行循环体中的代码,每次循环将 $x 减去 1,直到 $x 小于 0 为止。< $imgWidth; $x++) {
for ($y = 0; $y < $limitY; $y++) {
$y_x = $imgWidth - $radius; //圆心X坐标
$y_y = $radius; //圆心Y坐标
$this->setRadius($img, $im, $x, $y, $y_x, $y_y, $radius);
}
}
// 左下
for ($x = 0; $x < $limitX; $x++) {
for ($y = $imgHeight - $limitY; $y < $imgHeight; $y++) {
$y_x = $radius; //圆心X坐标
$y_y = $imgHeight - $radius; //圆心Y坐标
$this->setRadius($img, $im, $x, $y, $y_x, $y_y, $radius);
}
}
// 右下
for ($x = $imgWidth - $limitX; $x < $imgWidth; $x++) {
for ($y = $imgHeight - $limitY; $y < $imgHeight; $y++) {
$y_x = $imgWidth -$radius; //圆心X坐标
$y_y = $imgHeight - $radius; //圆心Y坐标
$this->setRadius($img, $im, $x, $y, $y_x, $y_y, $radius);
}
}
return $im;
}
首页首先创建一个背景图,此背景图是透明的。接着,将 logo 中的像素点复制到该背景图里。对于四个圆角部分的处理,是通过 setRadius 方法来进行的。
设置半径的函数为 setRadius,它接收参数 $img、$im、$x、$y、$circleX、$circleY 和 $radius。该函数用于在特定的图像相关操作中设置半径相关的参数。
$val1 等于 ($x 减去 $circleX) 乘以 ($x 减去 $circleX) 加上 ($y 减去 $circleY) 乘以 ($y 减去 $circleY)
$val2 = $radius * $radius;
在图像 $img 中,获取坐标 ($x, $y) 处的颜色值,将其存储在变量 $rgbColor 中。
if ($val1 <= $val2) {
imagesetpixel($im, $x, $y, $rgbColor);
}
// 除锯齿
if($val1 > $val2 && $val1 <= ($radius + 0.3) * ($radius + 0.3)) {
$rgbColor = imagecolorat($img, $x, $y);
$img_pix_array = imagecolorsforindex($im, $rgbColor);
imagesetpixel($im, $x, $y, imagecolorallocatealpha($img, $img_pix_array['red'], $img_pix_array['green'], $img_pix_array['blue'], intval((127 - $img_pix_array['alpha']) * 0.3)));
}
if($val1 >$radius 加上 0.3 之后再乘以$radius 加上 0.3 ,并且$val1<= ($radius + 0.7) * ($radius + 0.7)) {
$rgbColor = imagecolorat($img, $x, $y);
$img_pix_array = imagecolorsforindex($im, $rgbColor);
imagesetpixel($im, $x, $y, imagecolorallocatealpha($img, $img_pix_array['red'], $img_pix_array['green'], $img_pix_array['blue'], intval((127 - $img_pix_array['alpha']) * 0.6)));
}
if($val1 >$radius 加上 0.7 后再乘以$radius 加上 0.7 的结果,并且这个结果与$val1 相关。<= ($radius + 0.98) * ($radius + 0.98)) {
$rgbColor = imagecolorat($img, $x, $y);
$img_pix_array = imagecolorsforindex($im, $rgbColor);
imagesetpixel($im, $x, $y, imagecolorallocatealpha($img, $img_pix_array['red'], $img_pix_array['green'], $img_pix_array['blue'], intval((127 - $img_pix_array['alpha']) * 0.8)));
}
}
利用圆的公式x2 + y2
« 上一篇
在安装无个性设置软件时将其安装到D盘的操作方法
下一篇 »
河南省人民医院尚佳:丙肝常被忽视,早筛早治可治愈