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

1次阅读

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 文件里加一行:<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
  • Linux/macOS 上还得装系统级依赖,比如 Ubuntu 要 sudo apt-get install libgdiplus
  • 若部署在容器里,记得在 Dockerfile 中提前安装对应库,否则运行时才报错,很难排查

Graphics.DrawLine 加干扰线,但线条太规律像网格

很多人用循环画一堆平行线,结果验证码背景全是整齐的斜线或横线,OCR 一扫就识别了——干扰线得“假乱”,不能真乱,更不能太密。

关键不是数量,是分布和形态:

  • Random 生成起点 / 终点时,别只用 Next(0, width),加点偏移,比如 Next(-10, width + 10),让线段自然“穿出”画布边缘
  • 线宽建议设为 1f0.8f,大于 1 容易连成块,削弱字符可读性
  • 颜色别用纯黑 / 纯白,从灰度区间选几个相近色,比如 Color.FromArgb(180, 180, 180)Color.FromArgb(210, 210, 210) 混着用
  • 避免水平 / 垂直 /45° 这三类角度扎堆,可用 Math.Atan2 配合随机向量构造自然倾斜

Bitmap.SetPixel 加噪点,但性能暴跌到 200ms 一张

逐像素调用 SetPixel 是最慢的写法,尤其在高 DPI 或大尺寸验证码下,CPU 占用飙升。这不是算法问题,是 API 本身开销太大。

换成位图内存操作,能压到 15ms 内:

  • 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 才真正“硬朗难啃”。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-23发表,共计1685字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources