go-qrcode仅支持生成二维码,不提供解析功能;解析必须使用gozxing。其encode返回*image.rgba对象,需用png.encode等手动编码为字节流,并正确设置content-type。

go-qrcode 只生成,不解析;想扫码得换 gozxing —— 这是绝大多数人踩坑前没意识到的第一件事。
qrcode.Encode 返回的是 *image.RGBA,不是 PNG 字节流
直接 fmt.Println(qrcode.Encode(...)) 会打印内存地址;w.Write(pngBytes) 却传了 *image.RGBA,结果浏览器显示乱码或 iOS Safari 拒绝加载。根本原因是:它返回的是 Go 原生图像对象,不是可直接传输的二进制图像。
- 必须用
png.Encode或jpeg.Encode手动编码:先创建bytes.Buffer或传入http.ResponseWriter,再调png.Encode(w, img) - HTTP 场景下,
Content-Type: image/png必须在png.Encode之前设置,且不能写任何其他响应头或 body - 若要输出 JPEG,不能只改文件后缀,得显式传
qrcode.WithImageType(qrcode.ImageTypeJPEG),否则仍是 PNG 内容 - 传
os.Stdout会乱码——终端不支持二进制图像流,适合重定向到文件:./qrgen "https://x.com" > q.png
WriteFile 和 Encode 的容错等级参数必须用常量,不能传数字或字符串
写 qrcode.WriteFile(url, 2, 256, "q.png") 看似合理,实际会静默降级为 Low 级别;写 "medium" 更糟——库不校验,但纠错数据生成错误,扫码失败率陡增。
- 合法值只有四个:
qrcode.Low、qrcode.Medium、qrcode.High、qrcode.Highest - 它们是
int类型别名,底层值为0~3,但别手动写数字,避免和未来版本语义脱钩 - Medium 是最稳选择:15% 容错率,体积与鲁棒性平衡;High/Highest 仅在需强抗损(如印刷品)时启用
中文、URL、特殊字符必须预处理,否则扫码器识别率断崖下跌
微信旧版、部分安卓扫码器对 UTF-8 字节流解析脆弱,不是库 bug,是现实兼容性边界。传原始中文或未解码 URL,大概率扫出乱码或空内容。
- 前端 URL 编码过的参数(如
text=https%3A%2F%2Fexample.com),后端务必先url.QueryUnescape - 纯中文内容建议先
url.PathEscape或url.QueryEscape,再喂给qrcode.Encode,提升各平台识别率 - 检查输入是否合法 UTF-8:
utf8.Valid([]byte(s)),非法字节(如截断的 emoji)会触发qrcode: content contains invalid characters - 避免全角标点、零宽空格(
)、BOM 头——这些字符不可见,但会让某些扫码器静默截断
解析二维码必须用 gozxing,qrcode 库完全不提供 decode 能力
试图用 github.com/skip2/go-qrcode 解码图片?它连 Decode 函数都没有。所有“qrcode.Decode”相关报错,根源都是误以为它双向支持。
- 正确路径:用
image.Decode读图 → 转为*image.Gray→ 传给gozxing.NewBinaryBitmapFromImage→qrReader.Decode - 注意灰度转换:JPEG/PNG 解码后通常是
*image.NRGBA或*image.RGBA,必须显式转灰度,否则gozxing返回nil - 模糊、反光、低对比度图大概率失败,
gozxing不做自动增强;真机拍摄前建议加简单锐化或二值化预处理 - 单图识别耗时 50–200ms,批量处理务必加
context.WithTimeout,防止 goroutine 卡死
最容易被忽略的其实是「纠错等级和内容长度的隐式耦合」:同样一个 URL,用 Highest 级别生成的二维码模块数可能比 Medium 多 40%,导致小尺寸(如 128×128)下无法容纳,直接 panic。别只看文档写的「支持容错」,先算模块总数再定 size。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











