Extractor.csusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing ;
using System.Drawing.Imaging;namespace CaptchaExtractor
{
/// <summary>
/// 解析器
/// </summary>
public static class Extractor
{
public static String Run(Bitmap value)
{
String Res = "";
Bitmap Resultbit = null;
Bitmap Resultbit1 = null;
Bitmap Resultbit2 = null;
Bitmap Resultbit3 = null;
Bitmap Resultbit4 = null;
List<Bitmap> Resultbit5 = null;
Bitmap Resultbit6 = null;
int ColorOffset = 5;
int SplitColorNum = 150;
Run(value, ColorOffset, SplitColorNum, out Res,
out Resultbit, out Resultbit1, out Resultbit2, out Resultbit3, out Resultbit4, out Resultbit5, out Resultbit6, "");
return Res;
}
/// <summary>
/// 执行
/// </summary>
/// <param name="value">图片内容</param>
/// <param name="colorOffset">颜色偏移量</param>
/// <param name="ResultText">返回文本内容</param>
/// <param name="ResultImage">返回最终图片</param>
/// <param name="LearnText">学习模式下图片内容的实际的值,非学习模式下为空</param>
public static String Run(Bitmap value,int colorOffset,int SplitColorNum,out String ResultText,out Bitmap ResultImage,
out Bitmap Image1,out Bitmap Image2,out Bitmap Image3,out Bitmap Image4,out List<Bitmap> Image5,out Bitmap Image6,
String LearnText)
{
/*方法
* 1、灰度
* 2、降色
* 3、计算
* 3、滤色
* 5、匹配
*/
#region 第一步,灰度
Bitmap GrayscaleBit = new Bitmap(value.Width, value.Height);
GrayscaleBit.SetResolution(value.HorizontalResolution, value.VerticalResolution); Graphics GrayG = Graphics.FromImage(GrayscaleBit);
Point sp1 = new Point (0,0);
Point sp2 = new Point (value.Width ,0);
Point sp3 = new Point (0,value.Height ); ImageAttributes newia = new ImageAttributes();
ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
newia.SetColorMatrix(colorMatrix);
GrayG.DrawImage(value, new Rectangle(0, 0, value.Width, value.Height), 0, 0, value.Width, value.Height, GraphicsUnit.Pixel, newia); #endregion
//第三步的计算的颜色统计
//Dictionary<int, int> ColorCollection = new Dictionary<int, int>();
List<int> ColorList = new List<int> ();
#region 第二步,降色,并丢色
Bitmap LessColorbit = new Bitmap(GrayscaleBit);
int ColorNum = 50;
for (int i = 0; i < LessColorbit.Width; i++)
{
for (int j = 0; j < LessColorbit.Height; j++)
{
//降色了
Color CurrColor = LessColorbit.GetPixel(i, j);
int ColorR = 0;
//直接丢色
#region 丢色
if (CurrColor.R > SplitColorNum)
{
//全白
ColorR = 255;
}
else
{
//全黑
ColorR = 0;
}
CurrColor = Color.FromArgb(255, ColorR, ColorR, ColorR);
LessColorbit.SetPixel(i, j, CurrColor);
#endregion
#region 降色
//if (CurrColor.R % ColorNum != 0)
//{
// //不是5的余数时
// ColorR = CurrColor.R / ColorNum * ColorNum ;
// CurrColor = Color.FromArgb(255, ColorR, ColorR, ColorR);
// LessColorbit.SetPixel(i, j, CurrColor );
//}
#endregion if (CurrColor .R != 255&& !ColorList.Exists(c => c == CurrColor.R))
{
ColorList.Add(CurrColor.R);
}
//if (ColorCollection.ContainsKey(CurrColor.R))
//{
// ColorCollection[CurrColor.R] += 1;
//}
//else
//{
// ColorCollection.Add(CurrColor.R, 1);
//}
}
}
#endregion #region 第三步,计算
//主要是为了计算深色
#endregion
#region 滤色
//颜色从深到浅,从左到右,逐步匹配
//List<int> ColorList = from ss in ColorCollection
// select ss.Key
ColorList.Sort();
//存储被匹配掉之后的图片
Bitmap Matchbit = new Bitmap(LessColorbit);
//存储被匹配出来的图片
Bitmap Filterbit = new Bitmap(LessColorbit);
Graphics MatchG = Graphics.FromImage(Matchbit); Graphics FilterG = Graphics.FromImage(Filterbit);
FilterG.Clear(Color.FromArgb(255, 255, 255, 255));
// Bitmap FindImage = new Bitmap (5,5);
// FindImage.SetResolution (72,72);
// Graphics FindG = Graphics.FromImage (FindImage );
// FindG.Clear (Color.FromArgb (255,188,167,20));
//MatchG.Clear(Color.FromArgb(0, 0, 0, 0));
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing ;
using System.Drawing.Imaging;namespace CaptchaExtractor
{
/// <summary>
/// 解析器
/// </summary>
public static class Extractor
{
public static String Run(Bitmap value)
{
String Res = "";
Bitmap Resultbit = null;
Bitmap Resultbit1 = null;
Bitmap Resultbit2 = null;
Bitmap Resultbit3 = null;
Bitmap Resultbit4 = null;
List<Bitmap> Resultbit5 = null;
Bitmap Resultbit6 = null;
int ColorOffset = 5;
int SplitColorNum = 150;
Run(value, ColorOffset, SplitColorNum, out Res,
out Resultbit, out Resultbit1, out Resultbit2, out Resultbit3, out Resultbit4, out Resultbit5, out Resultbit6, "");
return Res;
}
/// <summary>
/// 执行
/// </summary>
/// <param name="value">图片内容</param>
/// <param name="colorOffset">颜色偏移量</param>
/// <param name="ResultText">返回文本内容</param>
/// <param name="ResultImage">返回最终图片</param>
/// <param name="LearnText">学习模式下图片内容的实际的值,非学习模式下为空</param>
public static String Run(Bitmap value,int colorOffset,int SplitColorNum,out String ResultText,out Bitmap ResultImage,
out Bitmap Image1,out Bitmap Image2,out Bitmap Image3,out Bitmap Image4,out List<Bitmap> Image5,out Bitmap Image6,
String LearnText)
{
/*方法
* 1、灰度
* 2、降色
* 3、计算
* 3、滤色
* 5、匹配
*/
#region 第一步,灰度
Bitmap GrayscaleBit = new Bitmap(value.Width, value.Height);
GrayscaleBit.SetResolution(value.HorizontalResolution, value.VerticalResolution); Graphics GrayG = Graphics.FromImage(GrayscaleBit);
Point sp1 = new Point (0,0);
Point sp2 = new Point (value.Width ,0);
Point sp3 = new Point (0,value.Height ); ImageAttributes newia = new ImageAttributes();
ColorMatrix colorMatrix = new System.Drawing.Imaging.ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
newia.SetColorMatrix(colorMatrix);
GrayG.DrawImage(value, new Rectangle(0, 0, value.Width, value.Height), 0, 0, value.Width, value.Height, GraphicsUnit.Pixel, newia); #endregion
//第三步的计算的颜色统计
//Dictionary<int, int> ColorCollection = new Dictionary<int, int>();
List<int> ColorList = new List<int> ();
#region 第二步,降色,并丢色
Bitmap LessColorbit = new Bitmap(GrayscaleBit);
int ColorNum = 50;
for (int i = 0; i < LessColorbit.Width; i++)
{
for (int j = 0; j < LessColorbit.Height; j++)
{
//降色了
Color CurrColor = LessColorbit.GetPixel(i, j);
int ColorR = 0;
//直接丢色
#region 丢色
if (CurrColor.R > SplitColorNum)
{
//全白
ColorR = 255;
}
else
{
//全黑
ColorR = 0;
}
CurrColor = Color.FromArgb(255, ColorR, ColorR, ColorR);
LessColorbit.SetPixel(i, j, CurrColor);
#endregion
#region 降色
//if (CurrColor.R % ColorNum != 0)
//{
// //不是5的余数时
// ColorR = CurrColor.R / ColorNum * ColorNum ;
// CurrColor = Color.FromArgb(255, ColorR, ColorR, ColorR);
// LessColorbit.SetPixel(i, j, CurrColor );
//}
#endregion if (CurrColor .R != 255&& !ColorList.Exists(c => c == CurrColor.R))
{
ColorList.Add(CurrColor.R);
}
//if (ColorCollection.ContainsKey(CurrColor.R))
//{
// ColorCollection[CurrColor.R] += 1;
//}
//else
//{
// ColorCollection.Add(CurrColor.R, 1);
//}
}
}
#endregion #region 第三步,计算
//主要是为了计算深色
#endregion
#region 滤色
//颜色从深到浅,从左到右,逐步匹配
//List<int> ColorList = from ss in ColorCollection
// select ss.Key
ColorList.Sort();
//存储被匹配掉之后的图片
Bitmap Matchbit = new Bitmap(LessColorbit);
//存储被匹配出来的图片
Bitmap Filterbit = new Bitmap(LessColorbit);
Graphics MatchG = Graphics.FromImage(Matchbit); Graphics FilterG = Graphics.FromImage(Filterbit);
FilterG.Clear(Color.FromArgb(255, 255, 255, 255));
// Bitmap FindImage = new Bitmap (5,5);
// FindImage.SetResolution (72,72);
// Graphics FindG = Graphics.FromImage (FindImage );
// FindG.Clear (Color.FromArgb (255,188,167,20));
//MatchG.Clear(Color.FromArgb(0, 0, 0, 0));
解决方案 »
- 如何控制两个datagridview绑定同一个属性类的问题~~~标题要长~~~~~~~~~~~~~~
- 求一高端正则
- 左边是一个treeview 右边我想根据在用户在treeview中选择不同的结点而显示不同的窗口(不是内容哦)!
- 向xml文档中插入空元素的问题
- 如何在VS2005下调试带有参数的程序呢?
- 各路英雄请进~一棘手的问题~
- c# 员工关系类 (分数送上)
- 怎么把null值传入数据库里类型为int的字段?
- 如何在.net中的winfom程序中实现有固定格式的表格报表
- 如果在winform中加入类似vb6中的webbrowser控件?C#中有吗?
- c#简单的添加不成功,求解
- 求助,关于windows media player
//颜色偏移量
int OffsetValue = colorOffset ; //现在只有两个颜色了,不需要用Dic来进行存储了
//Dictionary<Point, List<Point>> FilterPointCollection = new Dictionary<Point, List<Point>>();
List<List<Point>> OriginalPoint = new List<List<Point>>();
List<List<Point>> DynamicPoint = new List<List<Point>>();
for (int i = 0; i < ColorList.Count;i++ )
{
int MatchColor = ColorList[i];
Boolean IsError = false;
int LostNum = -999;
//遍历颜色,从深往浅
Point TopLeftP = new Point(LessColorbit.Width, LessColorbit.Height);
Point BottomRightP = new Point(0, 0); List<Point> findPoint = new List<Point>();
//从左往右寻找
for (int x = 0; x < LessColorbit.Width; x++)
{
Boolean IsFind = false;
for (int y = 0; y < LessColorbit.Height; y++)
{
if ((x == 37 || x == 36)&&
(y==9||y==8))
{ }
//好了
if (ContrastColor(LessColorbit.GetPixel(x, y).R, MatchColor, OffsetValue))
{
if (x < TopLeftP.X)
TopLeftP.X = x;
if (y < TopLeftP.Y)
TopLeftP.Y = y;
if (x > BottomRightP.X)
BottomRightP.X = x;
if (y > BottomRightP.Y)
BottomRightP.Y = y;
findPoint .Add (new Point (x,y));
IsFind = true;
}
}
if (IsFind)
{
if (LostNum == -999)
LostNum = 0;
//如果太宽,则错了
if (((BottomRightP.X - TopLeftP.X) > LessColorbit.Width / 4) ||
((BottomRightP.Y - TopLeftP.Y) > LessColorbit.Height * 0.8))
{
IsError = true;
break;
}
}
else
{
LostNum = 1;
}
if (LostNum == 1)
{
//如果太窄,则错了
if (BottomRightP.X - TopLeftP.X >= 6)
{ //这里说明,矩阵存在,并且当前已经到了边界
//好吧,去处理下
//MatchG.DrawImage(FindImage, new Rectangle(TopLeftP.X + 1, TopLeftP.Y + 1, BottomRightP.X - TopLeftP.X, BottomRightP.Y - TopLeftP.Y), new Rectangle(0, 0, FindImage.Width, FindImage.Height), GraphicsUnit.Pixel);
//goto ffff;
//fillPointColor(Matchbit,Filterbit , findPoint);
//if (FilterPointCollection.ContainsKey(TopLeftP))
//{
//foreach (Point FP in findPoint)
//{
// if (!FilterPointCollection[TopLeftP].Exists(c => c.Equals(FP)))
// {
// FilterPointCollection[TopLeftP].Add(FP);
// }
//}
//}
//else
//{
// FilterPointCollection.Add(TopLeftP, findPoint);
//}
//保存在图片中的原像素点,以及相对相素点
OriginalPoint.Add(findPoint);
DynamicPoint.Add(GetDynamicPoint (findPoint ));
}
findPoint = new List<Point>();
LostNum = -999;
TopLeftP = new Point(Matchbit.Width, Matchbit.Height);
BottomRightP = new Point(0, 0);
}
if (IsError)
break;
}
}
ffff:
#endregion Bitmap Findbit = new Bitmap(LessColorbit,new Size (800,60) );
//Findbit.SetResolution(72, 72);
Graphics FindG = Graphics.FromImage(Findbit);
FindG.Clear(Color.FromArgb(255, 255, 255, 255)); int DrawIndex = 0;
int CurrHei = 0;
int CurrWid = 0;
List<Bitmap> ResolveImages = new List<Bitmap>();
Boolean IsLearn = !String.IsNullOrEmpty (LearnText );
List<CaptchaValue> TextMatch = CaptchTextManager.GetAll();
String Text = "";
//foreach (KeyValuePair<Point, List<Point>> tmpValue in FilterPointCollection)
foreach (List<Point> tmpValue in DynamicPoint )
{
if (IsLearn)
{
if (String.IsNullOrEmpty(LearnText))
break;
String CurrText = LearnText[0].ToString();
if (CurrText != " ")
{
CaptchTextManager.Learn(tmpValue, CurrText );
}
if (LearnText.Length == 1)
{
LearnText = "";
}
else
{
LearnText = LearnText.Substring(1, LearnText.Length - 1);
}
}
else
{
//遍历结果
Bitmap tmpbit = new Bitmap(LessColorbit);
Graphics tmpg = Graphics.FromImage(tmpbit);
tmpg.Clear(Color.FromArgb(255, 255, 255, 255));
Point TopLeft = new Point(tmpbit.Width, tmpbit.Height);
Point BottomRight = new Point(0, 0);
foreach (Point tmpP in tmpValue)
{
tmpbit.SetPixel(tmpP.X, tmpP.Y, Color.FromArgb(255, 0, 0, 0));
if (tmpP.X < TopLeft.X)
TopLeft.X = tmpP.X;
if (tmpP.Y < TopLeft.Y)
TopLeft.Y = tmpP.Y;
if (tmpP.X > BottomRight.X)
BottomRight.X = tmpP.X;
if (tmpP.Y > BottomRight.Y)
BottomRight.Y = tmpP.Y;
}
//好了,结束
int wid = BottomRight.X - TopLeft.X + 1;
int hei = BottomRight.Y - TopLeft.Y + 1;
if (CurrWid + wid > 800)
{
CurrWid = 0;
CurrHei += 20;
}
FindG.DrawImage(tmpbit, new Rectangle(CurrWid, CurrHei, wid, hei), new Rectangle(TopLeft.X, TopLeft.Y, wid, hei), GraphicsUnit.Pixel);
CurrWid += wid + 5;
} //好了,解码
Text += ResloveCodebyDic(TextMatch, tmpValue, 3); //ResolveImages.Add(ResolveCode(tmpValue.Value));
}
ResultText = Text ;
ResultImage = LessColorbit ;
Image1 = GrayscaleBit;
Image2 = LessColorbit;
Image3 = Matchbit;
Image4 = Filterbit;
Image5 = ResolveImages;
Image6 = Findbit;
return Text;
} private static void fillPointColor(Bitmap b,Bitmap f, List<Point> value)
{
//Graphics ddd = Graphics.FromImage(b);
foreach (Point pp in value)
{
b.SetPixel(pp.X, pp.Y , Color.FromArgb(255, 255, 255, 255));
f.SetPixel(pp.X, pp.Y, Color.FromArgb(255, 0, 0, 0));
}
}
/// <summary>
/// 匹配颜色
/// </summary>
/// <param name="CurrCol">当前的颜色</param>
/// <param name="MatchCol">参照颜色</param>
/// <param name="OffsetValue">偏移量</param>
/// <returns></returns>
private static Boolean ContrastColor(int CurrCol, int MatchCol, int OffsetValue)
{
if (( CurrCol == MatchCol )||
(CurrCol < MatchCol &&CurrCol + OffsetValue >=MatchCol )||
(CurrCol > MatchCol && CurrCol - OffsetValue <= MatchCol ))
{
return true;
}
return false;
}
/// 把取得的像素点,重置到左上角
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private static List<Point> GetDynamicPoint(List<Point> value)
{
Point TopLeft = new Point(1000, 1000);
//Point BottomRight = new Point(0, 0);
//第一步,找出顶点
foreach (Point tmpv in value)
{
if (tmpv.X < TopLeft.X)
TopLeft.X = tmpv.X;
if (tmpv.Y < TopLeft.Y)
TopLeft.Y = tmpv.Y;
}
List<Point> res = new List<Point>();
for (int i = 0; i < value.Count;i++ )
{
Point tmpv = value[i];
res.Add (new Point(tmpv.X - TopLeft.X, tmpv.Y - TopLeft.Y));
}
return res;
} /// <summary>
/// 智能解码,不用了
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private static Bitmap ResolveCode(List<Point> value)
{
Font newf = new Font("宋体",18);
//第一步,计算长宽
Bitmap Drawbit = new Bitmap(1500, 30);
Drawbit.SetResolution(72, 72);
Graphics DrawG = Graphics.FromImage(Drawbit);
DrawG.Clear(Color.FromArgb(255, 255, 255, 255)); int DrawWidth = 0; Point TopLeft = new Point(200,200);
Point BottomRight = new Point(0, 0);
foreach (Point tmpP in value )
{
Drawbit.SetPixel(tmpP.X, tmpP.Y, Color.FromArgb(255, 0, 0, 0));
if (tmpP.X < TopLeft.X)
TopLeft.X = tmpP.X;
if (tmpP.Y < TopLeft.Y)
TopLeft.Y = tmpP.Y;
if (tmpP.X > BottomRight.X)
BottomRight.X = tmpP.X;
if (tmpP.Y > BottomRight.Y)
BottomRight.Y = tmpP.Y;
}
//好了,结束
int wid = BottomRight.X - TopLeft.X + 1;
int hei = BottomRight.Y - TopLeft.Y + 1; DrawWidth = TopLeft .X + wid + 1;
String Dic = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < Dic.Length;i++ )
{
char tmpC = Dic[i];
Bitmap newB = new Bitmap(200, 200);
newB.SetResolution(72, 72);
Graphics newG = Graphics.FromImage(newB);
newG.Clear(Color.FromArgb(255, 255, 255, 255));
newG.DrawString(tmpC.ToString (), newf, new SolidBrush(Color.FromArgb(255, 0, 0, 0)), new RectangleF(TopLeft, new SizeF(wid, hei)));
//好了,来比比
//取百分比吧
int DonePointNum = 0;
foreach (Point tmpP in value)
{
if (newB.GetPixel(tmpP.X, tmpP.Y).R != 255)
{
//成了
newB.SetPixel(tmpP.X, tmpP.Y, Color.FromArgb(255, 128, 128, 128));
DonePointNum++;
}
}
DrawG.DrawImage(newB, new Rectangle(DrawWidth, TopLeft.Y, wid, hei), new Rectangle(TopLeft.X, TopLeft.Y, wid, hei), GraphicsUnit.Pixel);
DrawWidth += wid + 1;
} return Drawbit;
} /// <summary>
/// 字典解码
/// </summary>
/// <param name="dic"></param>
/// <param name="value"></param>
/// <param name="Offset"></param>
/// <returns></returns>
private static String ResloveCodebyDic(List<CaptchaValue> dic, List<Point> value,int Offset)
{
String Text = "¤";
if (dic != null && dic.Count > 0 && value != null && value.Count > 0)
{
//Dictionary<String, int> Result = new Dictionary<string, int>();
int allMaxNum = 0;
foreach (CaptchaValue tmpV in dic)
{
//Result.Add(tmpV.Text, 0);
int MaxNum = 0;
//值有效,可以继续
for (int i = -1*Offset ; i <= Offset; i++)
{
for (int j = -1*Offset ; j <= Offset; j++)
{
int MatchNum = MatchPoint(tmpV.Value, value, i, j);
if (MatchNum > MaxNum)
MaxNum = MatchNum;
}
}
if (MaxNum > allMaxNum )
{
allMaxNum = MaxNum ;
if (MaxNum * 2 >= tmpV.Value.Count )
{
Text = tmpV.Text;
}
}
//Result[tmpV.Text] = MaxNum;
}
//好了,执行完了
}
return Text;
}
private static int MatchPoint(List<Point> p1, List<Point> p2, int xOffset, int yOffset)
{
int MatchNum = 0;
if (p1 != null && p1.Count > 0 &&
p2 != null && p2.Count > 0)
{
foreach (Point tmpP in p1)
{
if (p2.Exists(c => c.X == tmpP.X + xOffset && c.Y == tmpP.Y + yOffset))
{
//能找到,说明成功了
MatchNum++;
}
}
}
return MatchNum;
}
}
}
http://www.zuidaima.com/share/1631472847784960.htm