qrcoder不支持logo叠加,需手动用bitmap合成;关键在安全区域计算(宽高的25%)、居中绘制及抗锯齿处理,否则会遮挡定位图案导致扫码失败。

直接说结论:QRCoder 本身不支持 Logo 叠加,但可以手动用 Bitmap 合成;关键不是“怎么加图”,而是“加在哪、留多大空、怎么抗锯齿”——否则 Logo 被裁、二维码扫不出。
为什么 QRCoder.GenerateQrCode() 返回的 Bitmap 不能直接 DrawImage 加 Logo?
因为默认生成的二维码是纯黑白像素块,没有预留中间区域,Logo 图片一旦覆盖上去,会压住核心定位图案(三个角上的 Finder Pattern)或 Timing Pattern,导致多数扫码器无法识别。QRCoder 的 QRCodeData 也不暴露模块坐标映射,没法“智能避开”。
- 错误做法:
qrCodeImage.DrawImage(logo, x, y)硬贴,x/y 估不准,Logo 偏一点就失效 - 正确思路:先算出安全区域尺寸 → 缩放 Logo 到该尺寸 → 居中绘制 → 边缘做简单抗锯齿(用
InterpolationMode.HighQualityBicubic) - 安全区域经验公式:
int safeSize = (int)(qrCodeImage.Width * 0.25);(即二维码宽高的 25%,不超过 Finder Pattern 内边距)
如何用 QRCoder + GDI+ 实现居中 Logo 且扫码稳定?
必须用 QRCodeGenerator.ECCLevel.Q 或更高容错(Q 或 H),否则加图后纠错能力不足。生成后不要直接操作原始 Bitmap,而要用新画布合成。
- 步骤一:调用
qrGenerator.CreateQrCode(data, QRCodeGenerator.ECCLevel.Q) - 步骤二:用
new QRCode(qrCodeData).GetGraphic(20)获取基础图(20 是缩放因子,别用 1,太小) - 步骤三:创建新
Bitmap(同尺寸),Graphics.FromImage()开启SmoothingMode.AntiAlias和InterpolationMode.HighQualityBicubic - 步骤四:先
DrawImage二维码图,再算new Rectangle(centerX - safeSize/2, centerY - safeSize/2, safeSize, safeSize)绘制 Logo
Logo 图片预处理的三个硬性要求
不是所有 PNG 都能直接用。扫码失败 70% 出在 Logo 本身。
- 必须为正方形(非等比缩放会导致变形压线),建议输入前用代码裁切:
logo = CropToSquare(logo) - 背景必须透明(Alpha 通道有效),纯白底 PNG 会盖住二维码白色模块,形成“伪黑块”,干扰解码
- 边缘避免细线条或高对比文字——Logo 自身复杂度越高,越容易触发二维码纠错边界;实测宽度 > 80px 的复杂图标失败率陡增
最易被忽略的一点:Graphics.DrawImage 默认使用 CompositingMode.SourceOver,但如果 Logo 有半透明灰度,会和底层二维码灰度混合出意外色值。稳妥做法是提前把 Logo 转成 1-bit Alpha(保留透明,其余全白),再绘制。











