跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C#怎么生成漂亮的验证码图片_C#如何添加干扰线与噪点【源码】

System.Drawing.Common在.NET 6+需显式引用并安装系统依赖;干扰线应“假乱”分布、控制线宽与颜色;禁用SetPixel改用LockBits优化噪点;字体需支持扭曲、字符单独旋转偏移、剔除易混字符,并设TextRenderingHint.SingleBitPerPixelGridFit。 用
System.Drawing
画验证码图片,但 .NET 6+ 默认不支持 在 .net core / .net 5+ 项目里直接用
system.drawing
生成图片,大概率会报错:
system.platformnotsupportedexception: system.drawing.common is not supported on this platform
。这是因为跨平台默认禁用了 gdi+ 依赖。不是代码写错了,是运行时没装对东西。 解决办法只有两个:要么降级回 .NET Framework(不推荐),要么给项目显式启用兼容模式: 在
.csproj
文件里加一行:
Linux/macOS 上还得装系统级依赖,比如 Ubuntu 要
sudo apt-get install libgdiplus
若部署在容器里,记得在 Dockerfile 中提前安装对应库,否则运行时才报错,很难排查
Graphics.DrawLine
加干扰线,但线条太规律像网格 很多人用循环画一堆平行线,结果验证码背景全是整齐的斜线或横线,OCR 一扫就识别了——干扰线得“假乱”,不能真乱,更不能太密。 关键不是数量,是分布和形态: 用
Random
生成起点/终点时,别只用
Next(0, width)
,加点偏移,比如
Next(-10, width + 10)
,让线段自然“穿出”画布边缘 线宽建议设为
1f
或
0.8f
,大于 1 容易连成块,削弱字符可读性 颜色别用纯黑/纯白,从灰度区间选几个相近色,比如
Color.FromArgb(180, 180, 180)
和
Color.FromArgb(210, 210, 210)
混着用 避免水平/垂直/45° 这三类角度扎堆,可用
Math.Atan2
配合随机向量构造自然倾斜
Bitmap.SetPixel
加噪点,但性能暴跌到 200ms 一张 逐像素调用
SetPixel
是最慢的写法,尤其在高 DPI 或大尺寸验证码下,CPU 占用飙升。这不是算法问题,是 API 本身开销太大。 换成位图内存操作,能压到 15ms 内: C知道 CSDN推出的一款AI技术问答工具 下载 用
Bitmap.LockBits
获取原始字节数组,按
PixelFormat.Format32bppArgb
锁定 用
Marshal.Copy
把像素数据拷进
byte[]
,直接改数组值,再拷回去 噪点密度控制在 0.5%~1.5%,太多影响识别,太少形同虚设;优先在字符轮廓外围撒点,别往笔画中间扎 如果只是简单项目,干脆用
Graphics.FillEllipse
画几百个半透小圆代替噪点,速度够用且更可控 字体和字符选择不当,导致验证码“看着像人,机器更爱认” 用默认
Microsoft Sans Serif
加粗 + 四位纯数字?等于给 OCR 托盘送餐。真正难识别的,是人眼能跳读、但破坏了字符连续性的组合。 实操上要卡三个点: 字体必须支持扭曲变形:优先选
FontFamily.GenericSansSerif
或开源字体如
Noto Sans
,避开带太多衬线或连笔的书法体 每个字符单独绘制,用不同
RotateTransform
角度(±8° 内),并微调 X/Y 偏移(±2px),禁止整体旋转整串文字 禁用易混淆字符:去掉
0/O/l/I/1
,用预定义集合如
"23456789ABCDEFGHJKMNPQRSTUVWXYZ"
,长度固定 4–5 位足够 最常被忽略的是抗锯齿开关:
graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit
会让字体边缘发虚,反而提升 OCR 准确率;改成
TextRenderingHint.SingleBitPerPixelGridFit
才真正“硬朗难啃”。

相关文章