zoukankan      html  css  js  c++  java
  • 验证码识别必备,c#分析bmp图形文件,一个有用的BMP图形分析类收藏

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

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

    C#代码如下:

    1. using System; 
    2. using CrazyCoder.Commom.IO; 
    3. namespace CrazyCoder.Common.Image 
    4.     /**//// <summary> 
    5.       /// BMP 的摘要说明。 
    6.       /// </summary> 
    7.       public class BMP 
    8.       { 
    9.           
    10.          public BMP() 
    11.          { 
    12.             // 
    13.              //TODO: 在此处添加构造函数逻辑 
    14.              
    15.              
    16.              //功能:分析bmp文件格式 
    17.              //本文参考了林福宗老师的有关BMP文件格式的文章 
    18.              
    19.             
    20.             // 
    21.          } 
    22.          /**//*BMP(BitMap-File)图形文件是Windows采用的图形文件格式,在Windows环境 
    23.           * 下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各 
    24.           * 图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与 
    25.           * 显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB 
    26.           * (device-dependent BitMap)文件格式。Windows 3.0以后的BMP图象文件与 
    27.          * 显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB 
    28.           * (device-independent BitMap)格式(注:Windows 3.0以后,在系统中仍 
    29.          * 然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将 
    30.          * 图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的 
    31.          * 是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件 
    32.         * 默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。 
    33.         * */ 
    34.          public struct StructBMP 
    35.          { 
    36.              public BMPHeader Header; 
    37.              public BMPPalette Palette; 
    38.              public BMPData Data; 
    39.          } 
    40.          public struct BMPHeader 
    41.          { 
    42.              /**//*位图文件可看成由4个部分组成:位图文件头(BitMap-file header)、 
    43.               * 位图信息头(BitMap-information header)、彩色表(color table)和 
    44.               * 定义位图的字节阵列, 
    45.               * */ 
    46.              public string Identifier;/**//*2 bytes,识别位图的类型:  
    47.              ‘BM’ : Windows 3.1x, 95, NT, …  
    48.             ‘BA’ :OS/2 BitMap Array  
    49.              ‘CI’ :OS/2 Color Icon  
    50.              ‘CP’ :OS/2 Color Pointer  
    51.              ‘IC’ : OS/2 Icon  
    52.              ‘PT’ :OS/2 Pointer  
    53.              注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。 
    54.              */  
    55.              public System.Int32 FileSize;//1 dword,用字节表示的整个文件的大小  
    56.              public byte[] Reserved;//1 dword,保留,必须设置为0  
    57.              public System.Int32 BitMapDataOffset;//1 dword,从文件开始到位图数据开始之间的数据(BitMap data)之间的偏移量 
    58.             public System.Int32 BitMapHeaderSize;/**//*1 dword 
    59.             位图信息头(BitMap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:  
    60.             28h - windows 3.1x, 95, nt, … 
    61.             0ch - os/2 1.x 
    62.              f0h - os/2 2.x 
    63.              注: 在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化 比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。  
    64.               */ 
    65.              public System.Int32 Width;//1 dword,位图的宽度,以象素为单位 
    66.              public System.Int32 Height;//1 dword,位图的高度,以象素为单位  
    67.              public System.Int16 Planes;//1 word,位图的位面数(注:该值将总是1)  
    68.             public System.Int16 BitsPerPixel; 
    69.              /**//*1 word 
    70.              每个象素的位数  
    71.              1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)  
    72.              4 - 16 色位图  
    73.              8 - 256 色位图  
    74.              16 - 16bit 高彩色位图  
    75.              24 - 24bit 真彩色位图  
    76.              32 - 32bit 增强型真彩色位图  
    77.              */  
    78.              public System.Int32 Compression; 
    79.              /**//*1 dword 
    80.             压缩说明:  
    81.             0 - 不压缩 (使用BI_RGB表示)  
    82.              1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示)  
    83.              2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示)  
    84.              3 - Bitfields-位域存放方式(用BI_BITFIELDS表示)  
    85.              */ 
    86.              public System.Int32 BitMapDataSize;//1 dword,用字节数表示的位图数据的大小。该数必须是4的倍数 
    87.              public System.Int32 HResolution;//1 dword,用象素/米表示的水平分辨率 
    88.              public System.Int32 VResolution;//1 dword,用象素/米表示的垂直分辨率 
    89.              public System.Int32 Colors;//1 dword,位图使用的颜色数。如8-比特/象素表示为100h或者 256.  
    90.             public System.Int32 ImportantColors; 
    91.             /**//*1 dword,指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要  
    92.             */ 
    93.         } 
    94.         public struct BMPPalette 
    95.          { 
    96.              public byte[] Palette;//new byte[8192];//bmp规范没有规定调色板最大81926字节,此处可以根据程序需要调节 
    97.              /**//*调色板数据根据BMP版本的不同而不同PaletteN * 4 byte调色板规范。 
    98.              对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值: 1字节用于蓝色分量  
    99.             1字节用于绿色分量  
    100.             1字节用于红色分量  
    101.             1字节用于填充符(设置为0)  
    102.            */ 
    103.         } 
    104.         public struct BMPData        { 
    105.             public byte[] BitMapData;//=new byte[1024000];//bmp规范没有规定bmp数据最多为1024000,此处可以根据需要调整 
    106.             /**//* 
    107.             图象数据根据BMP版本及调色板尺寸的不同而不同BitMap Dataxxx bytes该域的大小取决 
    108.             于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是 
    109.             彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。 
    110.             */ 
    111.         } 
    112.         public void ProcessBMP(ref StructBMP sbmp,byte[] bytesFile) 
    113.         { 
    114.             byte[] word1=new byte[2]; 
    115.             byte[] word2=new byte[4]; 
    116.             System.Int32 result; 
    117.             string str=""
    118.             word1[0]=bytesFile[0]; 
    119.             word1[1]=bytesFile[1]; 
    120.             str=FromBytesToString(word1); 
    121.             sbmp.Header.Identifier=str; 
    122.             word2[0]=bytesFile[2]; 
    123.             word2[1]=bytesFile[3]; 
    124.             word2[2]=bytesFile[4]; 
    125.             word2[3]=bytesFile[5]; 
    126.             result=this.FromBytesToInt32(word2); 
    127.            sbmp.Header.FileSize=result; 
    128.             word2[0]=bytesFile[10]; 
    129.            word2[1]=bytesFile[11]; 
    130.             word2[2]=bytesFile[12]; 
    131.             word2[3]=bytesFile[13]; 
    132.             result=this.FromBytesToInt32(word2); 
    133.             sbmp.Header.BitMapDataOffset=result; 
    134.             word2[0]=bytesFile[14]; 
    135.             word2[1]=bytesFile[15]; 
    136.             word2[2]=bytesFile[16]; 
    137.             word2[3]=bytesFile[17]; 
    138.             result=this.FromBytesToInt32(word2); 
    139. 141            sbmp.Header.BitMapHeaderSize=result; 
    140.             word2[0]=bytesFile[18]; 
    141.             word2[1]=bytesFile[19]; 
    142.             word2[2]=bytesFile[20]; 
    143.             word2[3]=bytesFile[21]; 
    144.             sbmp.Header.Width=result; 
    145.            word2[0]=bytesFile[22]; 
    146.            word2[1]=bytesFile[23]; 
    147.             word2[2]=bytesFile[24]; 
    148.             word2[3]=bytesFile[25]; 
    149.             result=this.FromBytesToInt32(word2); 
    150.             sbmp.Header.Height =result; 
    151.             word1[0]=bytesFile[26]; 
    152.             word1[1]=bytesFile[27]; 
    153.             sbmp.Header.Planes=(System.Int16)FromBytesToInt32(word1); 
    154.             word1[0]=bytesFile[28]; 
    155.             word1[1]=bytesFile[29]; 
    156.             sbmp.Header.BitsPerPixel=(System.Int16)FromBytesToInt32(word1); 
    157.             word2[0]=bytesFile[30]; 
    158.             word2[1]=bytesFile[31]; 
    159.             word2[2]=bytesFile[32]; 
    160.             word2[3]=bytesFile[33]; 
    161.             result=this.FromBytesToInt32(word2); 
    162.             sbmp.Header.Compression =result; 
    163.             word2[0]=bytesFile[34]; 
    164.             word2[1]=bytesFile[35]; 
    165.             word2[2]=bytesFile[36]; 
    166.             word2[3]=bytesFile[37]; 
    167.             result=this.FromBytesToInt32(word2); 
    168.             sbmp.Header.BitMapDataSize  =result; 
    169.             word2[0]=bytesFile[38]; 
    170.             word2[1]=bytesFile[39]; 
    171.             word2[2]=bytesFile[40]; 
    172.             word2[3]=bytesFile[41]; 
    173.             result=this.FromBytesToInt32(word2); 
    174.             sbmp.Header.HResolution  =result; 
    175.            word2[0]=bytesFile[42]; 
    176.             word2[1]=bytesFile[43]; 
    177.             word2[2]=bytesFile[44]; 
    178.             word2[3]=bytesFile[45]; 
    179.             result=this.FromBytesToInt32(word2); 
    180.             sbmp.Header.VResolution =result; 
    181.             word2[0]=bytesFile[46]; 
    182.             word2[1]=bytesFile[47]; 
    183.             word2[2]=bytesFile[48]; 
    184.             word2[3]=bytesFile[49]; 
    185.             result=this.FromBytesToInt32(word2); 
    186.             sbmp.Header.Colors =result; 
    187.             word2[0]=bytesFile[50]; 
    188.            word2[1]=bytesFile[51]; 
    189.             word2[2]=bytesFile[52]; 
    190.             word2[3]=bytesFile[53]; 
    191.             result=this.FromBytesToInt32(word2); 
    192.             sbmp.Header.ImportantColors =result; 
    193.             //计算位图数据的开始位置 
    194.             //sbmp.Header.BitMapDataSize是位图数据的大小,sbmp.Header.FileSize是整个文件的大小 
    195.             //sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-1就是位图数据的开始位置 
    196.             //0x36到sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-2就是调色板数据 
    197.             result=sbmp.Header.FileSize-sbmp.Header.BitMapDataSize; 
    198.             int j=0; 
    199.             byte[] b=new byte[sbmp.Header.BitMapDataSize]; 
    200.             for(int i=result;i<sbmp.Header.FileSize;i++) 
    201.             { 
    202.                 b[j]=bytesFile[i];j++; 
    203.             } 
    204.             sbmp.Data.BitMapData=b; 
    205.             j=0; 
    206.             b=new byte[result-sbmp.Header.BitMapDataOffset]; 
    207.             for(int i=sbmp.Header.BitMapDataOffset;i<result;i++) 
    208.             { 
    209.                 b[j]=bytesFile[i];j++; 
    210.             } 
    211.             sbmp.Palette.Palette=b; 
    212.         } 
    213.         public void ProcessBMP(ref StructBMP sbmp,string File) 
    214.         { 
    215.             //先读取文件成字节数组,统一由ProcessBMP(StructBMP sbmp,byte[] bytesFile)处理 
    216.             JJBase.FILE.ReadAndWrite  f=new ReadAndWrite(); 
    217.             byte[] result=f.ReadBytesFromFile(File); 
    218.            ProcessBMP(ref sbmp,result); 
    219.         } 
    220.         private System.Int32 FromBytesToInt32(byte[] b) 
    221.         { 
    222.             System.Int32 result=0; 
    223.             System.Int32 t=0; 
    224.             for(int i=b.Length-1;i>=0;i--) 
    225.             { 
    226.                  
    227.                 if((int)b[i]!=0) 
    228.                 { 
    229.                     t=(int)Math.Pow(256,i); 
    230.                     result+=(int)b[i]*t; 
    231.                 } 
    232.                  
    233.             } 
    234.             return result; 
    235.         } 
    236.         private string FromBytesToString(byte[] b) 
    237.        { 
    238.             string result=""
    239.             for(int i=0;i<b.Length;i++) 
    240.             { 
    241.                 result+=Convert.ToChar((int)(b[i])).ToString(); 
    242.             } 
    243.             return result; 
    244.         } 
    245.          
    246.     } 
    247. 方法2:
    248. using System; 
    249. using System.Collections.Generic; 
    250. using System.Text; 
    251. using System.Drawing; 
    252. namespace CrazyCoder.Common.Decode 
    253.     public class GanjiImageDecode : CrazyCoder.Common.Decode.ImageDeCodeBase 
    254.     { 
    255.         public GanjiImageDecode(Bitmap pic) : base(pic) { } 
    256.         public GanjiImageDecode(string path) : base(path) { } 
    257.        
    258.         //特征码数组 
    259.         string[] CodeArray = new string[] { 
    260. "00011111000001111111000111000111001100000110110000000111100000001111000000011110000000111100000001101100000110011100011100011111110000011111000",//0 
    261. "0111111110110011001100110011001100110011001100110011",//1 
    262. "001111100011111110110000111000000011000000011000000110000001110000111000001110000011000000110000000111111111111111111",//2 
    263. "001111100011111110110000111000000011000000011000000111000011110000011110000000111000000011110000111011111110001111100",//3 
    264. "00000011100000000111000000011110000001101100000110011000011000110001100001100111000011001111111111111111111111000000011000000000110000000001100",//4 
    265. "111111110111111110110000000110000000110000000111111000000001110000000111000000011000000011010000111111111110011111100",//5 
    266. "0001111000001111111001110001000110000000110000000011001111001111111110111000011111000000110110000011011100011100111111100001111100",//6 
    267. "11111111111111110000011000001100000011000001100000110000001100000010000001100000011000000110000001100000",//7 
    268. "001111100011111110111000111110000011111000111011111110011111110111000111110000011110000011111000111011111110001111100",//8 
    269. "0011111000011111110011100011101100000110110000011111100011110111111011001111001100000000110000000110001000111001111111000011111000",//9 
    270. "11111111"//- 
    271.         }; 
    272.         public Bitmap[] GetPic() 
    273.         { 
    274.             ToGrayByPixels(); //灰度处理 
    275.             Bitmap bmp = GetPicValidByValue(128); 
    276.             Bitmap[] pics = GetSplitPics2(bmp,128);   //分割 
    277.             for (int i = 0; i < pics.Length; i++) 
    278.             { 
    279.                 if (pics[i] != null
    280.                 { 
    281.                     Bitmap b = pics[i]; 
    282.                     pics[i] = GetPicValidByValue(pics[i], 128); 
    283.                     b.Dispose(); 
    284.                 } 
    285.             } 
    286.             return pics; 
    287.         } 
    288.         public string GetCodeString() 
    289.         { 
    290.             Bitmap[] pics = GetPic(); 
    291.             string numStr = ""
    292.             for (int i = 0; i < pics.Length; i++) 
    293.             { 
    294.                 string str = GanjiImageDecode.GetSingleBmpCode(pics[i], 128); 
    295.                 for (int j = 0; j < CodeArray.Length; j++) 
    296.                 { 
    297.                     if (CodeArray[j] == str) 
    298.                     { 
    299.                         if (j < CodeArray.Length - 1) 
    300.                         { 
    301.                             numStr += j.ToString(); 
    302.                         } 
    303.                         else 
    304.                         { 
    305.                             numStr += "-"
    306.                         } 
    307.                     } 
    308.                 } 
    309.             } 
    310.             return numStr; 
    311.         } 
    312.     } 
  • 相关阅读:
    栈的实现
    函数传值 传地址 传引用的区别【转】
    sql server数据库最大Id冲突问题解决方法之一
    c#3.5关于JSON简单操作的实用帮助类(泛型实现)
    OLLYDBG
    SocketException.ErrorCode 列表及注释,Winsocket Error 列表及注释
    Netbeans5.5.1 连接 Mysql
    大型互联网网站架构心得之一:任务拆分
    工作流(WF)中使用SqlWorkflowPersistenceService创建完全的持久性服务
    Windows Phone学习笔记
  • 原文地址:https://www.cnblogs.com/liehuo123/p/5562274.html
Copyright © 2011-2022 走看看