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