BMP图形文件分析类(c#)

    技术2022-05-11  50

    1using System;  2using JJBase.FILE;  3namespace JJBase.Image  4{  5    /// <summary>  6    /// BMP 的摘要说明。  7    /// </summary>  8    public class BMP  9    { 10         11        public BMP() 12        { 13            // 14            //TODO: 在此处添加构造函数逻辑 15            //作者:梁俊杰 16            //时间:2005-9-29 17            //功能:分析bmp文件格式 18            //本文参考了林福宗老师的有关BMP文件格式的文章 19            //参考链接:http://www.chinahacker.net/article/showarticle.asp?articleid=20809 20            //参考链接:http://www.moon-soft.com/program/FORMAT/graphics/Bmp.html 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 BMPData106        {107            public byte[] BitMapData;//=new byte[1024000];//bmp规范没有规定bmp数据最多为1024000,此处可以根据需要调整108            /*109            图象数据根据BMP版本及调色板尺寸的不同而不同BitMap Dataxxx bytes该域的大小取决110            于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是111            彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。112            */113        }114        public void ProcessBMP(ref StructBMP sbmp,byte[] bytesFile)115        {116            byte[] word1=new byte[2];117            byte[] word2=new byte[4];118            System.Int32 result;119            string str="";120            word1[0]=bytesFile[0];121            word1[1]=bytesFile[1];122            str=FromBytesToString(word1);123            sbmp.Header.Identifier=str;124            word2[0]=bytesFile[2];125            word2[1]=bytesFile[3];126            word2[2]=bytesFile[4];127            word2[3]=bytesFile[5];128            result=this.FromBytesToInt32(word2);129            sbmp.Header.FileSize=result;130            word2[0]=bytesFile[10];131            word2[1]=bytesFile[11];132            word2[2]=bytesFile[12];133            word2[3]=bytesFile[13];134            result=this.FromBytesToInt32(word2);135            sbmp.Header.BitMapDataOffset=result;136            word2[0]=bytesFile[14];137            word2[1]=bytesFile[15];138            word2[2]=bytesFile[16];139            word2[3]=bytesFile[17];140            result=this.FromBytesToInt32(word2);141            sbmp.Header.BitMapHeaderSize=result;142            word2[0]=bytesFile[18];143            word2[1]=bytesFile[19];144            word2[2]=bytesFile[20];145            word2[3]=bytesFile[21];146            sbmp.Header.Width=result;147            word2[0]=bytesFile[22];148            word2[1]=bytesFile[23];149            word2[2]=bytesFile[24];150            word2[3]=bytesFile[25];151            result=this.FromBytesToInt32(word2);152            sbmp.Header.Height =result;153            word1[0]=bytesFile[26];154            word1[1]=bytesFile[27];155            sbmp.Header.Planes=(System.Int16)FromBytesToInt32(word1);156            word1[0]=bytesFile[28];157            word1[1]=bytesFile[29];158            sbmp.Header.BitsPerPixel=(System.Int16)FromBytesToInt32(word1);159            word2[0]=bytesFile[30];160            word2[1]=bytesFile[31];161            word2[2]=bytesFile[32];162            word2[3]=bytesFile[33];163            result=this.FromBytesToInt32(word2);164            sbmp.Header.Compression =result;165            word2[0]=bytesFile[34];166            word2[1]=bytesFile[35];167            word2[2]=bytesFile[36];168            word2[3]=bytesFile[37];169            result=this.FromBytesToInt32(word2);170            sbmp.Header.BitMapDataSize  =result;171            word2[0]=bytesFile[38];172            word2[1]=bytesFile[39];173            word2[2]=bytesFile[40];174            word2[3]=bytesFile[41];175            result=this.FromBytesToInt32(word2);176            sbmp.Header.HResolution  =result;177            word2[0]=bytesFile[42];178            word2[1]=bytesFile[43];179            word2[2]=bytesFile[44];180            word2[3]=bytesFile[45];181            result=this.FromBytesToInt32(word2);182            sbmp.Header.VResolution =result;183            word2[0]=bytesFile[46];184            word2[1]=bytesFile[47];185            word2[2]=bytesFile[48];186            word2[3]=bytesFile[49];187            result=this.FromBytesToInt32(word2);188            sbmp.Header.Colors =result;189            word2[0]=bytesFile[50];190            word2[1]=bytesFile[51];191            word2[2]=bytesFile[52];192            word2[3]=bytesFile[53];193            result=this.FromBytesToInt32(word2);194            sbmp.Header.ImportantColors =result;195            //计算位图数据的开始位置196            //sbmp.Header.BitMapDataSize是位图数据的大小,sbmp.Header.FileSize是整个文件的大小197            //sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-1就是位图数据的开始位置198            //0x36到sbmp.Header.FileSize-sbmp.Header.BitMapDataSize-2就是调色板数据199            result=sbmp.Header.FileSize-sbmp.Header.BitMapDataSize;200            int j=0;201            byte[] b=new byte[sbmp.Header.BitMapDataSize];202            for(int i=result;i<sbmp.Header.FileSize;i++)203            {204                b[j]=bytesFile[i];j++;205            }206            sbmp.Data.BitMapData=b;207            j=0;208            b=new byte[result-sbmp.Header.BitMapDataOffset];209            for(int i=sbmp.Header.BitMapDataOffset;i<result;i++)210            {211                b[j]=bytesFile[i];j++;212            }213            sbmp.Palette.Palette=b;214        }215        public void ProcessBMP(ref StructBMP sbmp,string File)216        {217            //先读取文件成字节数组,统一由ProcessBMP(StructBMP sbmp,byte[] bytesFile)处理218            JJBase.FILE.ReadAndWrite  f=new ReadAndWrite();219            byte[] result=f.ReadBytesFromFile(File);220            ProcessBMP(ref sbmp,result);221        }222        private System.Int32 FromBytesToInt32(byte[] b)223        {224            System.Int32 result=0;225            System.Int32 t=0;226            for(int i=b.Length-1;i>=0;i--)227            {228                229                if((int)b[i]!=0)230                {231                    t=(int)Math.Pow(256,i);232                    result+=(int)b[i]*t;233                }234                235            }236            return result;237        }238        private string FromBytesToString(byte[] b)239        {240            string result="";241            for(int i=0;i<b.Length;i++)242            {243                result+=Convert.ToChar((int)(b[i])).ToString();244            }245            return result;246        }247        248    }249}


    最新回复(0)