点击蓝字 关注我们


在 LINK PAY 收银系统小程序平台上,不少商家提出了一个共性需求:希望在店铺专属的小程序码 / 二维码中嵌入自己的店铺 Logo,而非默认显示的小程序头像。


通常情况下,无论是通过微信小程序 MP 官方后台的小程序码生成工具,还是调用官方服务端 API 生成的小程序码,都不支持自定义 Logo,生成的二维码默认会使用小程序的头像(如下图所示)。



临时解决方案:借助第三方工具实现部分需求

若仅针对单个店铺的个性化需求,可通过 “草料二维码” 工具的 “小程序参数码” 功能,生成指向店铺主页的小程序二维码,再利用该工具的 “二维码美化排版” 功能替换成店铺 Logo。不过,这种方法存在明显局限 —— 仅能生成二维码,无法生成小程序码,难以完全满足商家对小程序码的使用需求。



通用解决方案:开发系统后台自动合成功能

正是看到了商家的这一普遍需求,我们意识到:若能在 LINK PAY 系统后台开发一项功能,让系统自动根据商家店铺的 Logo 生成带自定义 Logo 的小程序码,必将成为深受商家欢迎的实用功能。最终效果如何所示:



由于微信官方服务端 API 生成的小程序码,其中间的 Logo 仅能调用小程序头像,无法直接替换,因此我们只能从 “后期处理已生成的小程序码图片” 入手。核心思路很简单:将商家店铺的 Logo 与生成好的小程序码进行图片合成叠加,用店铺 Logo 覆盖掉小程序码上默认的头像 Logo,从而得到带自定义 Logo 的小程序码。


然而,思路虽清晰,实际开发却充满细节挑战,仅调试就耗费了一整晚。关键难点在于:


需将商家上传的店铺 Logo 处理成圆形且背景为透明的 PNG 格式图片;

合成后的 Logo 背景色不能变成黑色或白色,必须保证视觉上 “毫无违和感”,达到 “无 PS 痕迹” 的自然效果。

针对上述需求与挑战,以下是实现该功能的核心代码:

/**
* 生成自定义Logo的小程序码
* @param string $wxCodeData 小程序码二进制数据
* @param string $directory 小程序码保存路径
* @param string $filename 小程序码文件名
* @param string $logoPath 替换新的logo图路径
* @return false|string
* @author jiang
*/
public static function generateCodeWithLogo($wxCodeData, string $directory, string $filename, $logoPath)
{
// 提前检查目录权限,避免后续处理后才发现问题
$directory = rtrim($directory, '/');
if (!is_dir($directory) && !mkdir($directory, 0755, true)) {
return false;
}
if (!is_writable($directory)) {
return false;
}

// 提前读取logo内容,减少文件操作
$logoContent = @file_get_contents($logoPath);
if ($logoContent === false) {
return false;
}

try {
// 创建小程序码图像资源并保留透明通道
$wxCode = imagecreatefromstring($wxCodeData);
if (!$wxCode) {
return false;
}
imagesavealpha($wxCode, true);
imagealphablending($wxCode, true);

// 获取小程序码尺寸并计算Logo大小(只计算一次)
$codeWidth = imagesx($wxCode);
$codeHeight = imagesy($wxCode);
$logoSize = (int)($codeWidth / 2.2); // 使用整数运算提高效率

// 处理Logo为圆形(带透明背景)
$logo = imagecreatefromstring($logoContent);
$logo = rounded_corner($logo); // 确保此函数返回带透明通道的图像
if (!$logo) {
imagedestroy($wxCode); // 及时释放资源
return false;
}

// 计算Logo位置(居中)
$logoX = ($codeWidth - $logoSize) / 2;
$logoY = ($codeHeight - $logoSize) / 2;
$borderSize = 5;
$borderedSize = $logoSize + $borderSize * 2;
$borderedHalfSize = $borderedSize / 2;

// 创建带边框的Logo画布(合并了原logoResizedborder步骤)
$borderedLogo = imagecreatetruecolor($borderedSize, $borderedSize);
imagesavealpha($borderedLogo, true);
$transparent = imagecolorallocatealpha($borderedLogo, 0, 0, 0, 127);
imagefill($borderedLogo, 0, 0, $transparent);

// 绘制白色圆形边框
$white = imagecolorallocate($borderedLogo, 255, 255, 255);
imagefilledellipse(
$borderedLogo,
$borderedHalfSize,
$borderedHalfSize,
$logoSize + $borderSize,
$logoSize + $borderSize,
$white
);

// 调整Logo大小并直接复制到带边框的画布(减少中间步骤)
imagealphablending($borderedLogo, true);
imagecopyresampled(
$borderedLogo,
$logo,
$borderSize, $borderSize, 0, 0,
$logoSize, $logoSize,
imagesx($logo), imagesy($logo)
);
imagesavealpha($borderedLogo, true);

// 释放不再需要的资源
imagedestroy($logo);

// 将带边框的Logo合成到小程序码
imagealphablending($wxCode, true); // 允许透明叠加
imagecopy(
$wxCode,
$borderedLogo,
$logoX - $borderSize,
$logoY - $borderSize,
0, 0,
$borderedSize,
$borderedSize
);

// 释放边框Logo资源
imagedestroy($borderedLogo);

// 保存合成后的图片
$savePath = $directory . '/' . $filename;
$saveResult = imagepng($wxCode, $savePath);

// 释放主图像资源
imagedestroy($wxCode);

return $saveResult ? $filename : false;

} catch (Exception $e) {
return false;
}
}


好了,有需要的同学可以拿去参考,这个核心逻辑使用PHP GD库来实现的,PHP需要安装GD库扩展哦。


END.


其他同学有更好的方案,或者优化建议,可以一起交流探讨哦~~~


gh_6052a9275cf9_1280 (1).jpg
LINK PAY 收银系统
一触即通,生意更轻松
https://jiangzi.xin
所有评论
加载评论 ...
发表评论