PHP QR Code 改变颜色
在 php 中,我们可以通过 phpqrcode
这个库来快速生成二维码。
QRcode::png ($text, $outfile=false, $level=QR_ECLEVEL_L, $size=3, $margin=4, $saveandprint=false)
但是,官方却没有暴露出设置二维码颜色和背景颜色的方法。
查看源码
于是,我们在 phpqrcode.php
中找到 QRcode::png()
这个方法
class QRcode {
// ...省略
public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false)
{
$enc = QRencode::factory($level, $size, $margin);
return $enc->encodePNG($text, $outfile, $saveandprint=false);
}
// ...省略
}
可以看到其实调用的是 QRencode->encodePNG()
方法
class QRencode {
// ...省略
public function encodePNG($intext, $outfile = false,$saveandprint=false)
{
try {
ob_start();
$tab = $this->encode($intext);
$err = ob_get_contents();
ob_end_clean();
if ($err != '')
QRtools::log($outfile, $err);
$maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
// 找到这个位置
QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
} catch (Exception $e) {
QRtools::log($outfile, $e->getMessage());
}
}
// ...省略
}
继续找到 QRimage::png()
class QRimage {
// ...省略
public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4, $saveandprint=FALSE)
{
// 找到这个位置
$image = self::image($frame, $pixelPerPoint, $outerFrame);
if ($filename === false) {
Header("Content-type: image/png");
ImagePng($image);
} else {
if($saveandprint===TRUE){
ImagePng($image, $filename);
header("Content-type: image/png");
ImagePng($image);
}else{
ImagePng($image, $filename);
}
}
ImageDestroy($image);
}
// ...省略
private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4)
{
$h = count($frame);
$w = strlen($frame[0]);
$imgW = $w + 2*$outerFrame;
$imgH = $h + 2*$outerFrame;
$base_image =ImageCreate($imgW, $imgH);
// 我们看到这里
$col[0] = ImageColorAllocate($base_image,255,255,255); // 设置白色背景
$col[1] = ImageColorAllocate($base_image,0,0,0); // 设置黑色内容
imagefill($base_image, 0, 0, $col[0]);
for($y=0; $y<$h; $y++) {
for($x=0; $x<$w; $x++) {
if ($frame[$y][$x] == '1') {
ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]);
}
}
}
$target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
ImageDestroy($base_image);
return $target_image;
}
}
解决方法
我们发现最后调用的是 QRimage::image()
,这里面就有关于二维码颜色的设置,只是官方默认设置成了“白纸黑字”,所以,我们只需修改 QRimage::image()
,并添加一个设置背景颜色的参数即可,其之上的方法也添加同样的参数
// 修改 QRimage::image()
private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4, $cols = [[255,255,255],[0,0,0]])
{
// ...省略
// 注释掉原来的
// $col[0] = ImageColorAllocate($base_image,255,255,255); // 设置白色背景
// $col[1] = ImageColorAllocate($base_image,0,0,0); // 设置黑色内容
// 设置我们自己传入的颜色
$col[0] = ImageColorAllocate($base_image,$cols[0][0],$cols[0][1],$cols[0][2]); // 设置自定义背景颜色
$col[1] = ImageColorAllocate($base_image,$cols[1][0],$cols[1][1],$cols[1][2]); // 设置自定义内容颜色
// ...省略
}
// ...省略 修改 QRencode::encodePNG()
QRencode::encodePNG($intext, $outfile = false,$saveandprint=false,$cols=[]) {}
// 修改 QRcode::png()
public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $cols=[], $saveandprint=false)
{
$enc = QRencode::factory($level, $size, $margin);
return $enc->encodePNG($text, $outfile, $saveandprint=false, $cols);
}
最后,我们通过生成可以变换颜色的二维码
$cols = [
[255,255,0], // 背景颜色
[255,0,255] // 二维码颜色
];
// 生成二维码图片
QRcode::png($value, $qrFilePath, $errorCorrectionLevel, $matrixPointSize, $margin, $cols);