验证码识别必备,c#分析bmp图形文件,一个有用的BMP图形分析类

以前帮朋友写的代码,现在公布出来,道理很简单的,切割,提取验证码,因为验证码字体并未重合,所以切割起来相当的简单,如果您要做分类信息的网站,采集还是可取的,识别率100%

疯狂代码原创发布,转载请注明出处

C#代码如下:

  1. using System;
  2. using CrazyCoder.Commom.IO;
  3. namespace CrazyCoder.Common.Image
  4. {
  5.     /**//// <summary>
  6.       /// BMP 的摘要说明。
  7.       /// </summary>
  8.       public class BMP
  9.       {
  10.          
  11.          public BMP()
  12.          {
  13.             //
  14.              //TODO: 在此处添加构造函数逻辑
  15.             
  16.             
  17.              //功能:分析bmp文件格式
  18.              //本文参考了林福宗老师的有关BMP文件格式的文章
  19.             
  20.            
  21.             //
  22.          }
  23.          /**//*BMP(BitMap-File)图形文件是Windows采用的图形文件格式,在Windows环境
  24.           * 下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各
  25.           * 图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与
  26.           * 显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB
  27.           * (device-dependent BitMap)文件格式。Windows 3.0以后的BMP图象文件与
  28.          * 显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB
  29.           * (device-independent BitMap)格式(注:Windows 3.0以后,在系统中仍
  30.          * 然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将
  31.          * 图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的
  32.          * 是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件
  33.         * 默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。
  34.         * */
  35.          public struct StructBMP
  36.          {
  37.              public BMPHeader Header;
  38.              public BMPPalette Palette;
  39.              public BMPData Data;
  40.          }
  41.          public struct BMPHeader
  42.          {
  43.              /**//*位图文件可看成由4个部分组成:位图文件头(BitMap-file header)、
  44.               * 位图信息头(BitMap-information header)、彩色表(color table)和
  45.               * 定义位图的字节阵列,
  46.               * */
  47.              public string Identifier;/**//*2 bytes,识别位图的类型: 
  48.              ‘BM’ : Windows 3.1x, 95, NT, … 
  49.             ‘BA’ :OS/2 BitMap Array 
  50.              ‘CI’ :OS/2 Color Icon 
  51.              ‘CP’ :OS/2 Color Pointer 
  52.              ‘IC’ : OS/2 Icon 
  53.              ‘PT’ :OS/2 Pointer 
  54.              注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。
  55.              */ 
  56.              public System.Int32 FileSize;//1 dword,用字节表示的整个文件的大小 
  57.              public byte[] Reserved;//1 dword,保留,必须设置为0 
  58.              public System.Int32 BitMapDataOffset;//1 dword,从文件开始到位图数据开始之间的数据(BitMap data)之间的偏移量
  59.             public System.Int32 BitMapHeaderSize;/**//*1 dword
  60.             位图信息头(BitMap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示: 
  61.             28h - windows 3.1x, 95, nt, …
  62.             0ch - os/2 1.x
  63.              f0h - os/2 2.x
  64.              注: 在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化 比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。 
  65.               */
  66.              public System.Int32 Width;//1 dword,位图的宽度,以象素为单位
  67.              public System.Int32 Height;//1 dword,位图的高度,以象素为单位 
  68.              public System.Int16 Planes;//1 word,位图的位面数(注:该值将总是1) 
  69.             public System.Int16 BitsPerPixel;
  70.              /**//*1 word
  71.              每个象素的位数 
  72.              1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色) 
  73.              4 - 16 色位图 
  74.              8 - 256 色位图 
  75.              16 - 16bit 高彩色位图 
  76.              24 - 24bit 真彩色位图 
  77.              32 - 32bit 增强型真彩色位图 
  78.              */ 
  79.              public System.Int32 Compression;
  80.              /**//*1 dword
  81.             压缩说明: 
  82.             0 - 不压缩 (使用BI_RGB表示) 
  83.              1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示) 
  84.              2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示) 
  85.              3 - Bitfields-位域存放方式(用BI_BITFIELDS表示) 
  86.              */
  87.              public System.Int32 BitMapDataSize;//1 dword,用字节数表示的位图数据的大小。该数必须是4的倍数
  88.              public System.Int32 HResolution;//1 dword,用象素/米表示的水平分辨率
  89.              public System.Int32 VResolution;//1 dword,用象素/米表示的垂直分辨率
  90.              public System.Int32 Colors;//1 dword,位图使用的颜色数。如8-比特/象素表示为100h或者 256. 
  91.             public System.Int32 ImportantColors;
  92.             /**//*1 dword,指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要 
  93.             */
  94.         }
  95.         public struct BMPPalette
  96.          {
  97.              public byte[] Palette;//new byte[8192];//bmp规范没有规定调色板最大81926字节,此处可以根据程序需要调节
  98.              /**//*调色板数据根据BMP版本的不同而不同PaletteN * 4 byte调色板规范。
  99.              对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值: 1字节用于蓝色分量 
  100.             1字节用于绿色分量 
  101.             1字节用于红色分量 
  102.             1字节用于填充符(设置为0) 
  103.            */
  104.         }
  105.         public struct BMPData        {
  106.             public byte[] BitMapData;//=new byte[1024000];//bmp规范没有规定bmp数据最多为1024000,此处可以根据需要调整
  107.             /**//*
  108.             图象数据根据BMP版本及调色板尺寸的不同而不同BitMap Dataxxx bytes该域的大小取决
  109.             于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是
  110.             彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。
  111.             */
  112.         }
  113.         public void ProcessBMP(ref StructBMP sbmp,byte[] bytesFile)
  114.         {
  115.             byte[] word1=new byte[2];
  116.             byte[] word2=new byte[4];
  117.             System.Int32 result;
  118.             string str="";
  119.             word1[0]=bytesFile[0];
  120.             word1[1]=bytesFile[1];
  121.             str=FromBytesToString(word1);
  122.             sbmp.Header.Identifier=str;
  123.             word2[0]=bytesFile[2];
  124.             word2[1]=bytesFile[3];
  125.             word2[2]=bytesFile[4];
  126.             word2[3]=bytesFile[5];
  127.             result=this.FromBytesToInt32(word2);
  128.            sbmp.Header.FileSize=result;
  129.             word2[0]=bytesFile[10];
  130.            word2[1]=bytesFile[11];
  131.             word2[2]=bytesFile[12];
  132.             word2[3]=bytesFile[13];
  133.             result=this.FromBytesToInt32(word2);
  134.             sbmp.Header.BitMapDataOffset=result;
  135.             word2[0]=bytesFile[14];
  136.             word2[1]=bytesFile[15];
  137.             word2[2]=bytesFile[16];
  138.             word2[3]=bytesFile[17];
  139.             result=this.FromBytesToInt32(word2);
  140. 141            sbmp.Header.BitMapHeaderSize=result;
  141.             word2[0]=bytesFile[18];
  142.             word2[1]=bytesFile[19];
  143.             word2[2]=bytesFile[20];
  144.             word2[3]=bytesFile[21];
  145.             sbmp.Header.Width=result;
  146.            word2[0]=bytesFile[22];
  147.            word2[1]=bytesFile[23];
  148.             word2[2]=bytesFile[24];
  149.             word2[3]=bytesFile[25];
  150.             result=this.FromBytesToInt32(word2);
  151.             sbmp.Header.Height =result;
  152.             word1[0]=bytesFile[26];
  153.             word1[1]=bytesFile[27];
  154.             sbmp.Header.Planes=(System.Int16)FromBytesToInt32(word1);
  155.             word1[0]=bytesFile[28];
  156.             word1[1]=bytesFile[29];
  157.             sbmp.Header.BitsPerPixel=(System.Int16)FromBytesToInt32(word1);
  158.             word2[0]=bytesFile[30];
  159.             word2[1]=bytesFile[31];
  160.             word2[2]=bytesFile[32];
  161.             word2[3]=bytesFile[33];
  162.             result=this.FromBytesToInt32(word2);
  163.             sbmp.Header.Compression =result;
  164.             word2[0]=bytesFile[34];
  165.             word2[1]=bytesFile[35];
  166.             word2[2]=bytesFile[36];
  167.             word2[3]=bytesFile[37];
  168.             result=this.FromBytesToInt32(word2);
  169.             sbmp.Header.BitMapDataSize  =result;
  170.             word2[0]=bytesFile[38];
  171.             word2[1]=bytesFile[39];
  172.             word2[2]=bytesFile[40];
  173.             word2[3]=bytesFile[41];
  174.             result=this.FromBytesToInt32(word2);
  175.             sbmp.Header.HResolution  =result;
  176.            word2[0]=bytesFile[42];
  177.             word2[1]=bytesFile[43];
  178.             word2[2]=bytesFile[44];
  179.             word2[3]=bytesFile[45];
  180.             result=this.FromBytesToInt32(word2);
  181.             sbmp.Header.VResolution =result;
  182.             word2[0]=bytesFile[46];
  183.             word2[1]=bytesFile[47];
  184.             word2[2]=bytesFile[48];
  185.             word2[3]=bytesFile[49];
  186.             result=this.FromBytesToInt32(word2);
  187.             sbmp.Header.Colors =result;
  188.             word2[0]=bytesFile[50];
  189.            word2[1]=bytesFile[51];
  190.             word2[2]=bytesFile[52];
  191.             word2[3]=bytesFile[53];
  192.             result=this.FromBytesToInt32(word2);
  193.             sbmp.Header.ImportantColors =result;
  194.             //计算位图数据的开始位置
  195.             //sbmp.Header.BitMapDataSize是位图数据的大小,sbmp.Header.FileSize是整个文件的大小
  196.             //sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-1就是位图数据的开始位置
  197.             //0x36到sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-2就是调色板数据
  198.             result=sbmp.Header.FileSize-sbmp.Header.BitMapDataSize;
  199.             int j=0;
  200.             byte[] b=new byte[sbmp.Header.BitMapDataSize];
  201.             for(int i=result;i<sbmp.Header.FileSize;i++)
  202.             {
  203.                 b[j]=bytesFile[i];j++;
  204.             }
  205.             sbmp.Data.BitMapData=b;
  206.             j=0;
  207.             b=new byte[result-sbmp.Header.BitMapDataOffset];
  208.             for(int i=sbmp.Header.BitMapDataOffset;i<result;i++)
  209.             {
  210.                 b[j]=bytesFile[i];j++;
  211.             }
  212.             sbmp.Palette.Palette=b;
  213.         }
  214.         public void ProcessBMP(ref StructBMP sbmp,string File)
  215.         {
  216.             //先读取文件成字节数组,统一由ProcessBMP(StructBMP sbmp,byte[] bytesFile)处理
  217.             JJBase.FILE.ReadAndWrite  f=new ReadAndWrite();
  218.             byte[] result=f.ReadBytesFromFile(File);
  219.            ProcessBMP(ref sbmp,result);
  220.         }
  221.         private System.Int32 FromBytesToInt32(byte[] b)
  222.         {
  223.             System.Int32 result=0;
  224.             System.Int32 t=0;
  225.             for(int i=b.Length-1;i>=0;i--)
  226.             {
  227.                 
  228.                 if((int)b[i]!=0)
  229.                 {
  230.                     t=(int)Math.Pow(256,i);
  231.                     result+=(int)b[i]*t;
  232.                 }
  233.                 
  234.             }
  235.             return result;
  236.         }
  237.         private string FromBytesToString(byte[] b)
  238.        {
  239.             string result="";
  240.             for(int i=0;i<b.Length;i++)
  241.             {
  242.                 result+=Convert.ToChar((int)(b[i])).ToString();
  243.             }
  244.             return result;
  245.         }
  246.         
  247.     }
  248. }

方法2:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Drawing;
  5. namespace CrazyCoder.Common.Decode
  6. {
  7.     public class GanjiImageDecode : CrazyCoder.Common.Decode.ImageDeCodeBase
  8.     {
  9.         public GanjiImageDecode(Bitmap pic) : base(pic) { }
  10.         public GanjiImageDecode(string path) : base(path) { }
  11.       
  12.         //特征码数组
  13.         string[] CodeArray = new string[] {
  14. "00011111000001111111000111000111001100000110110000000111100000001111000000011110000000111100000001101100000110011100011100011111110000011111000",//0
  15. "0111111110110011001100110011001100110011001100110011",//1
  16. "001111100011111110110000111000000011000000011000000110000001110000111000001110000011000000110000000111111111111111111",//2
  17. "001111100011111110110000111000000011000000011000000111000011110000011110000000111000000011110000111011111110001111100",//3
  18. "00000011100000000111000000011110000001101100000110011000011000110001100001100111000011001111111111111111111111000000011000000000110000000001100",//4
  19. "111111110111111110110000000110000000110000000111111000000001110000000111000000011000000011010000111111111110011111100",//5
  20. "0001111000001111111001110001000110000000110000000011001111001111111110111000011111000000110110000011011100011100111111100001111100",//6
  21. "11111111111111110000011000001100000011000001100000110000001100000010000001100000011000000110000001100000",//7
  22. "001111100011111110111000111110000011111000111011111110011111110111000111110000011110000011111000111011111110001111100",//8
  23. "0011111000011111110011100011101100000110110000011111100011110111111011001111001100000000110000000110001000111001111111000011111000",//9
  24. "11111111"//-
  25.         };
  26.         public Bitmap[] GetPic()
  27.         {
  28.             ToGrayByPixels(); //灰度处理
  29.             Bitmap bmp = GetPicValidByValue(128);
  30.             Bitmap[] pics = GetSplitPics2(bmp,128);   //分割
  31.             for (int i = 0; i < pics.Length; i++)
  32.             {
  33.                 if (pics[i] != null)
  34.                 {
  35.                     Bitmap b = pics[i];
  36.                     pics[i] = GetPicValidByValue(pics[i], 128);
  37.                     b.Dispose();
  38.                 }
  39.             }
  40.             return pics;
  41.         }
  42.         public string GetCodeString()
  43.         {
  44.             Bitmap[] pics = GetPic();
  45.             string numStr = "";
  46.             for (int i = 0; i < pics.Length; i++)
  47.             {
  48.                 string str = GanjiImageDecode.GetSingleBmpCode(pics[i], 128);
  49.                 for (int j = 0; j < CodeArray.Length; j++)
  50.                 {
  51.                     if (CodeArray[j] == str)
  52.                     {
  53.                         if (j < CodeArray.Length - 1)
  54.                         {
  55.                             numStr += j.ToString();
  56.                         }
  57.                         else
  58.                         {
  59.                             numStr += "-";
  60.                         }
  61.                     }
  62.                 }
  63.             }
  64.             return numStr;
  65.         }
  66.     }
  67. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值