Skip to content

Commit 3793a9e

Browse files
committed
upload project
1 parent 8b8c8f2 commit 3793a9e

30 files changed

+3620
-0
lines changed

code/CodeHelper.cs

Lines changed: 386 additions & 0 deletions
Large diffs are not rendered by default.

code/CodeInfo.cs

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
using System.IO;
6+
using System.Drawing;
7+
using System.Runtime.Serialization.Formatters.Binary;
8+
using System.Drawing.Imaging;
9+
10+
namespace VerifyReader
11+
{
12+
[Serializable]
13+
public class CodeInfo
14+
{
15+
private string _Url;
16+
/// <summary>
17+
/// 配置验证码时候的URL 识别并不使用
18+
/// </summary>
19+
public string Url {
20+
get { return _Url; }
21+
set { _Url = value; }
22+
}
23+
24+
private Image _ImageTemp;
25+
/// <summary>
26+
/// 配置验证码时候的图像 识别并不使用
27+
/// </summary>
28+
public Image ImageTemp {
29+
get { return _ImageTemp; }
30+
set { _ImageTemp = value; }
31+
}
32+
33+
private int _CodeCount;
34+
/// <summary>
35+
/// 验证码字符的个数
36+
/// </summary>
37+
public int CodeCount {
38+
get { return _CodeCount; }
39+
set { _CodeCount = value; }
40+
}
41+
42+
private byte[] _BinaryValues;
43+
/// <summary>
44+
/// 验证码二值化阈值
45+
/// </summary>
46+
public byte[] BinaryValues {
47+
get { return _BinaryValues; }
48+
set { _BinaryValues = value; }
49+
}
50+
51+
private int _PixelMin;
52+
/// <summary>
53+
/// 连通像素的最小像素点个数
54+
/// </summary>
55+
public int PixelMin {
56+
get { return _PixelMin; }
57+
set { _PixelMin = value; }
58+
}
59+
60+
private int _PixelMax;
61+
/// <summary>
62+
/// 连通像素的最大像素点个数
63+
/// </summary>
64+
public int PixelMax {
65+
get { return _PixelMax; }
66+
set { _PixelMax = value; }
67+
}
68+
69+
private Rectangle _RectangleCut;
70+
/// <summary>
71+
/// 验证码的裁剪区域
72+
/// </summary>
73+
public Rectangle RectangleCut {
74+
get { return _RectangleCut; }
75+
set { _RectangleCut = value; }
76+
}
77+
78+
private bool _IsAutoSelectRect;
79+
/// <summary>
80+
/// 是否是自动识别验证码字符区域
81+
/// </summary>
82+
public bool IsAutoSelectRect {
83+
get { return _IsAutoSelectRect; }
84+
set { _IsAutoSelectRect = value; }
85+
}
86+
87+
private List<Rectangle> _CodeRectangles;
88+
/// <summary>
89+
/// 验证码字符所在的区域 IsAutoSelectRect=true 时无效
90+
/// </summary>
91+
public List<Rectangle> CodeRectangles {
92+
get {
93+
if (_CodeRectangles == null) _CodeRectangles = new List<Rectangle>();
94+
return _CodeRectangles;
95+
}
96+
}
97+
98+
private List<string> _Express;
99+
/// <summary>
100+
/// 二值化时去干扰表达式
101+
/// </summary>
102+
public List<string> Express {
103+
get {
104+
if (_Express == null) _Express = new List<string>();
105+
return _Express;
106+
}
107+
}
108+
109+
private Dictionary<char, List<Image>> m_dic_char_img;
110+
private Dictionary<string, int> m_dic_img_hash = new Dictionary<string, int>();
111+
112+
public CodeInfo() {
113+
m_dic_char_img = new Dictionary<char, List<Image>>();
114+
}
115+
/// <summary>
116+
/// 添加一个验证码样本
117+
/// </summary>
118+
/// <param name="ch">验证码字符</param>
119+
/// <param name="imgCode">验证码图像</param>
120+
/// <returns>是否添加成功</returns>
121+
public bool AddCode(char ch, Image imgCode) {
122+
string strHash = this.GetImageHash(imgCode);
123+
if (m_dic_img_hash.ContainsKey(strHash)) return false;
124+
m_dic_img_hash.Add(strHash, 0);
125+
if (m_dic_char_img.ContainsKey(ch)) {
126+
m_dic_char_img[ch].Add(imgCode);
127+
} else {
128+
List<Image> lstBmpCode = new List<Image>();
129+
lstBmpCode.Add(imgCode);
130+
m_dic_char_img.Add(ch, lstBmpCode);
131+
}
132+
return true;
133+
}
134+
/// <summary>
135+
/// 根据字符获取该字符下的所有样本图像
136+
/// </summary>
137+
/// <param name="ch">目标字符</param>
138+
/// <returns>样本列表</returns>
139+
public List<Image> GetCodeImages(char ch) {
140+
if (m_dic_char_img.ContainsKey(ch)) {
141+
return m_dic_char_img[ch];
142+
}
143+
return null;
144+
}
145+
/// <summary>
146+
/// 删除目标字符下的所有样本图像
147+
/// </summary>
148+
/// <param name="ch">目标字符</param>
149+
public void RemoveCode(char ch) {
150+
if (!m_dic_char_img.ContainsKey(ch)) return;
151+
foreach (var v in m_dic_char_img[ch]) {
152+
string strHash = this.GetImageHash(v);
153+
if (m_dic_img_hash.ContainsKey(strHash))
154+
m_dic_img_hash.Remove(strHash);
155+
}
156+
m_dic_char_img.Remove(ch);
157+
}
158+
/// <summary>
159+
/// 删除目标字符中指定样本
160+
/// </summary>
161+
/// <param name="ch">目标字符</param>
162+
/// <param name="imgCode">目标图像</param>
163+
public void RemoveCode(char ch, Image imgCode) {
164+
m_dic_char_img[ch].Remove(imgCode);
165+
string strHash = this.GetImageHash(imgCode);
166+
if (m_dic_img_hash.ContainsKey(strHash))
167+
m_dic_img_hash.Remove(strHash);
168+
}
169+
/// <summary>
170+
/// 清除所有验证码样本
171+
/// </summary>
172+
public void ClearCode() {
173+
m_dic_char_img.Clear();
174+
m_dic_img_hash.Clear();
175+
}
176+
/// <summary>
177+
/// 获取现有的验证码字符
178+
/// </summary>
179+
/// <returns></returns>
180+
public Dictionary<char, List<Image>>.KeyCollection GetChars() {
181+
return m_dic_char_img.Keys;
182+
}
183+
/// <summary>
184+
/// 获取图像hash
185+
/// </summary>
186+
/// <param name="img">图像</param>
187+
/// <returns>hash</returns>
188+
private string GetImageHash(Image img) {
189+
using (MemoryStream ms = new MemoryStream()) {
190+
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
191+
byte[] byImg = new byte[ms.Length];
192+
ms.Seek(0, SeekOrigin.Begin);
193+
ms.Read(byImg, 0, byImg.Length);
194+
return BitConverter.ToString(System.Security.Cryptography.MD5.Create().ComputeHash(byImg)).Replace("-", "");
195+
}
196+
}
197+
/// <summary>
198+
/// 刷行图像hash 反序列化后图像hash可能有所变化
199+
/// </summary>
200+
private void RefreshHash() {
201+
m_dic_img_hash.Clear();
202+
foreach (var v in m_dic_char_img) {
203+
foreach (var i in v.Value) {
204+
m_dic_img_hash.Add(this.GetImageHash(i), 0);
205+
}
206+
}
207+
}
208+
/// <summary>
209+
/// 将目标配置保存到文件中
210+
/// </summary>
211+
/// <param name="ci">目标配置</param>
212+
/// <param name="strFileName">配置文件名(.ci.png后缀以图片形式保存配置 方便查看)</param>
213+
public static void SaveToFile(CodeInfo ci, string strFileName) {
214+
byte[] byci = null;
215+
byte[] bylen = null;
216+
using (MemoryStream ms = new MemoryStream()) {
217+
BinaryFormatter bf = new BinaryFormatter();
218+
bf.Serialize(ms, ci);
219+
byci = ms.ToArray();
220+
}
221+
if (System.Text.RegularExpressions.Regex.IsMatch(strFileName.ToLower(), @"\.ci\.png$")) {
222+
ci.ImageTemp.Save(strFileName, System.Drawing.Imaging.ImageFormat.Png);
223+
bylen = BitConverter.GetBytes(byci.Length);
224+
}
225+
using (FileStream fs = new FileStream(strFileName, FileMode.OpenOrCreate)) {
226+
fs.Position = fs.Length;
227+
fs.Write(byci, 0, byci.Length);
228+
if (bylen != null) fs.Write(bylen, 0, bylen.Length);
229+
}
230+
}
231+
/// <summary>
232+
/// 从文件中导入配置
233+
/// </summary>
234+
/// <param name="strFileName">文件名</param>
235+
/// <returns>验证码配置</returns>
236+
public static CodeInfo LoadFromFile(string strFileName) {
237+
byte[] byTemp = File.ReadAllBytes(strFileName);
238+
byte[] byCi = null;
239+
if (System.Text.RegularExpressions.Regex.IsMatch(strFileName.ToLower(), @"\.ci\.png$")) {
240+
byCi = new byte[BitConverter.ToInt32(byTemp, byTemp.Length - 4)];
241+
Array.Copy(byTemp, byTemp.Length - byCi.Length - 4, byCi, 0, byCi.Length);
242+
}
243+
using (MemoryStream fs = new MemoryStream(byCi == null ? byTemp : byCi)) {
244+
BinaryFormatter bf = new BinaryFormatter();
245+
CodeInfo ci = (CodeInfo)bf.Deserialize(fs);
246+
ci.RefreshHash();
247+
return ci;
248+
}
249+
}
250+
}
251+
}
30 KB
Loading
36.8 KB
Loading
27.7 KB
Loading
51 KB
Loading
29.1 KB
Loading
25.7 KB
Loading
5 KB
Loading
1.96 KB
Loading

0 commit comments

Comments
 (0)