最快用 qrcode.writefile,但 api 中禁用;应改用 qrcode.encode 返回 *image.nrgba,再用 png.encode 写入 responsewriter,需提前设 content-type,容错选 qrcode.medium,中文须 utf-8 验证并限长 2048 字。

直接用 qrcode.WriteFile 最快,但 API 服务里千万别这么干
生成一个本地 PNG 文件,qrcode.WriteFile 确实一行搞定,适合脚本或调试。但它内部会打开文件、编码、写盘——HTTP 接口里调用等于每次请求都落盘,既慢又容易触发权限或磁盘满错误。
- API 场景必须改用
qrcode.Encode:它返回*image.NRGBA,再交给png.Encode写入http.ResponseWriter,全程内存流转 - 别漏设响应头:
w.Header().Set("Content-Type", "image/png")必须在png.Encode之前调用,否则浏览器当文本渲染乱码 -
qrcode.Encode第三个参数是像素尺寸(如256),不是 DPI,也不是模块数;传0或负数会 panic
qrcode.Medium 是默认平衡点,别传数字硬编码容错等级
纠错等级影响扫码鲁棒性,也决定二维码矩阵大小。传 qrcode.Medium(15% 容错)对大多数链接够用;qrcode.High(25%)适合脏污/反光场景,但相同内容会生成更大矩阵,可能让小尺寸图变糊。
- 容错常量是
int类型别名,但库内部做了校验;传1或2虽能编译,但行为未定义,某些版本静默退化为Low - 中文内容不建议盲目拉高容错,先确保输入是合法 UTF-8:
utf8.Valid([]byte(s)),再考虑用url.QueryEscape编码后生成 - 超长文本(>2KB)会卡住或返回空图,接口里务必加长度拦截:
if len(text) > 2048 { http.Error(w, "text too long", http.StatusBadRequest); return }
想改颜色?别信 WithQRCodeColor,得自己遍历像素重绘
go-qrcode 原生只输出黑白像素(黑点是 0x000000ff,白底是 0xffffffff)。所谓“自定义颜色”其实是拿到 *image.NRGBA 后手动替换像素值,WithQRCodeColor 这类选项在 v1.4+ 已废弃,用了也没效果。
- 正确做法:双层循环遍历
img.Bounds(),用img.NRGBAAt(x, y)取像素,判断是否接近黑色(如r ),再用 <code>img.SetNRGBA(x, y, rNew, gNew, bNew, 0xff)覆盖 - 注意 Go 的
color.NRGBA分量是 16 位(0–65535),传 0–255 需左移 8 位:uint8(r) * 0x100 - 背景色同理:对所有非黑点设背景色,比“先填背景再画前景”更稳,避免 quiet zone(四周留白区)被漏掉
加 Logo 不是贴图那么简单,定位角标不能遮
Logo 必须居中、缩放、裁剪后叠加,但关键约束是:三个定位角标(左上、右上、左下)绝对不能被覆盖,否则大部分扫码器无法识别。
- Logo 尺寸建议 ≤ 二维码总面积的 30%,且宽高比尽量接近正方形,避免拉伸变形
- 叠加用
draw.Draw+draw.Over模式,offset 计算要基于qrImg.Bounds()和logo.Bounds(),别硬写(128, 128) - 别用
jpeg.Encode导出——PNG 支持透明通道,JPEG 强制转会导致黑底或色偏,库本身也不保证 JPEG 兼容性
Go 生态里没有“开箱即用”的彩色带标二维码方案,所有定制都建立在你愿意处理像素、坐标和图像合成的基础上。最容易被忽略的是 quiet zone 的完整性、响应头顺序、以及并发时 PNG 编码的 CPU 开销——这些地方一松懈,线上就出问题。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











