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.     } 
  • 相关阅读:
    2021.1.28 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2021.1.23 个人rating赛补题报告
    2020.12.14 个人训练赛补题报告
    2020.11.28 2020团体程序设计天梯赛补题报告
    2020.12.3 Codeforces Beta Round #73(Div2)补题报告
    Xhorse VVDI Prog V5.0.6 is Ready for BCM2 Adapter
    Program 2021 Ford Bronco All Keys Lost using VVDI Key Tool Plus
    Xhorse VVDI Prog V5.0.4 Software Update in July 2021
    How to use Xhorse VVDI2 to Exchange BMW FEM/BDC Module?
  • 原文地址:https://www.cnblogs.com/liehuo123/p/5562274.html
Copyright © 2011-2022 走看看