BMP图像格式详解及VB函数截图保存.doc

上传人:文库蛋蛋多 文档编号:2389278 上传时间:2023-02-17 格式:DOC 页数:10 大小:42.50KB
返回 下载 相关 举报
BMP图像格式详解及VB函数截图保存.doc_第1页
第1页 / 共10页
BMP图像格式详解及VB函数截图保存.doc_第2页
第2页 / 共10页
BMP图像格式详解及VB函数截图保存.doc_第3页
第3页 / 共10页
BMP图像格式详解及VB函数截图保存.doc_第4页
第4页 / 共10页
BMP图像格式详解及VB函数截图保存.doc_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《BMP图像格式详解及VB函数截图保存.doc》由会员分享,可在线阅读,更多相关《BMP图像格式详解及VB函数截图保存.doc(10页珍藏版)》请在三一办公上搜索。

1、BMP图像格式详解及VB截图保存方法2012-03-06 13:14BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。 由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。文件结构:典型的BMP图像文件由四部分组成:1:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息

2、;2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。位图的类型:位图一共有两种类型,即:设备相关位图(DDB)和设备无关位图(DIB)。DDB位图在早期的Windows系统(Windows 3.0以前)中是很普遍的,事实上它也是唯一的。然而,随着显示器制造技术的进步,以及显示设备的多样化,DDB位图的一些固有的问题开始浮现出来了

3、。比如,它不能够存储(或者说获取)创建这张图片的原始设备的分辨率,这样,应用程序就不能快速的判断客户机的显示设备是否适合显示这张图片。为了解决这一难题,微软创建了DIB位图格式。设备无关位图 (Device-Independent Bitmap)DIB位图包含下列的颜色和尺寸信息: 原始设备(即创建图片的设备)的颜色格式。 原始设备的分辨率。 原始设备的调色板 一个位数组,由红、绿、蓝(RGB)三个值代表一个像素。 一个数组压缩标志,用于表明数据的压缩方案(如果需要的话)。以上这些信息保存在BITMAPINFO结构中,该结构由BITMAPINFOHEADER结构和两个或更多个RGBQUAD结构

4、所组成。BITMAPINFOHEADER结构所包含的成员表明了图像的尺寸、原始设备的颜色格式、以及数据压缩方案等信息。RGBQUAD结构标识了像素所用到的颜色数据。DIB位图也有两种形式,即:底到上型DIB(bottom-up),和顶到下型DIB(top-down)。底到上型DIB的原点(origin)在图像的左下角,而顶到下型DIB的原点在图像的左上角。如果DIB的高度值(由BITMAPINFOHEADER结构中的biHeight成员标识)是一个正值,那么就表明这个DIB是一个底到上型DIB,如果高度值是一个负值,那么它就是一个顶到下型DIB。注意:顶到下型的DIB位图是不能被压缩的。位图的

5、颜色格式是通过颜色面板值(planes)和颜色位值(bitcount)计算得来的,颜色面板值永远是1,而颜色位值则可以是1、4、8、16、24、32其中的一个。如果它是1,则表示位图是一张单色位图(译者注:通常是黑白位图,只有黑和白两种颜色,当然它也可以是任意两种指定的颜色),如果它是4,则表示这是一张VGA位图,如果它是8、16、24、或是32,则表示该位图是其他设备所产生的位图。如果应用程序想获取当前显示设备(或打印机)的颜色位值(或称位深度),可调用API函数GetDeviceCaps(),并将第二个参数设为BITSPIXEL即可。显示设备的分辨率是以每米多少个像素来表明的,应用程序可以

6、通过以下三个步骤来获取显示设备或打印机的水平分辨率:1. 调用GetDeviceCaps()函数,指定第二个参数为HORZRES。2. 再次调用GetDeviceCaps()函数,指定第二个参数为HORZSIZE。3. 用第一个返回值除以第二个返回值。即:GetDeviceCaps(hDC,HORZRES)/GetDeviceCaps(hDC,HORZSIZE);应用程序也可以使用相同的三个步骤来获取设备的垂直分辨率,不同之处只是要将HORZRES替换为VERTRES,把HORZSIZE替换为VERTSIZE,即可。调色板是被保存在一个RGBQUAD结构的数组中,该结构指出了每一种颜色的红、绿

7、、蓝的分量值。位数组中的每一个索引都对应于一个调色板项(即一个RGBQUAD结构),应用程序将根据这种对应关系,将像素索引值转换为像素RGB值(真实的像素颜色)。应用程序也可以通过调用GetDeviceCaps()函数来获取当前显示设备的调色板尺寸(将该函数的第二个参数设为NUMCOLORS即可)。Win32 API支持位数据的压缩(只对8位和4位的底到上型DIB位图)。压缩方法是采用运行长度编码方案(RLE),RLE使用两个字节来描述一个句法,第一个字节表示重复像素的个数,第二个字节表示重复像素的索引值。有关压缩位图的详细信息请参见对BITMAPINFOHEADER结构的解释。应用程序可以从

8、一个DDB位图创建出一个DIB位图,步骤是,先初始化一些必要的结构,然后再调用GetDIBits()函数。不过,有些显示设备有可能不支持这个函数,你可以通过调用GetDeviceCaps()函数来确定一下(GetDeviceCaps()函数在调用时指定RC_DI_BITMAP作为RASTERCAPS的标志)。应用程序可以用DIB去设置显示设备上的像素(译者注:也就是显示DIB),方法是调用SetDIBitsToDevice()函数或调用StretchDIBits()函数。同样,有些显示设备也有可能不支持以上这两个函数,这时你可以指定RC_DIBTODEV作为RASTERCAPS标志,然后调用G

9、etDeviceCaps()函数来判断该设备是否支持SetDIBitsToDevice()函数。也可以指定RC_STRETCHDIB作为RASTERCAPS标志来调用GetDeviceCaps()函数,来判断该设备是否支持StretchDIBits()函数。如果应用程序只是要简单的显示一个已经存在的DIB位图,那么它只要调用SetDIBitsToDevice()函数就可以。比如一个电子表格软件,它可以打开一个图表文件,在窗口中简单的调用SetDIBitsToDevice()函数,将图形显示在窗口中。但如果应用程序要重复的绘制位图的话,则应该使用BitBlt()函数,因为BitBlt()函数的执

10、行速度要比SetDIBitsToDevice()函数快很多。设备相关位图 (Device-Dependent Bitmaps)设备相关位图(DDB)之所以现在还被系统支持,只是为了兼容旧的Windows 3.0软件,如果程序员现在要开发一个与位图有关的程序,则应该尽量使用或生成DIB格式的位图。DDB位图是被一个单个结构BITMAP所描述,这个结构的成员标明了该位图的宽度、高度、设备的颜色格式等信息。DDB位图也有两种类型,即:可废弃的(discardable)DDB和不可废弃的(nondiscardable)DDB。可废弃的DDB位图就是一种当系统内存缺乏,并且该位图也没有被选入设备描述表(

11、DC)的时候,系统就会把该DDB位图从内存中清除(即废弃)。不可废弃的DDB则是无论系统内存多少都不会被系统清除的DDB。API函数CreateDiscardableBitmap()函数可用于创建可废弃位图。而函数CreateBitmap()、CreateCompatibleBitmap()、和CreateBitmapIndirect()可用于创建不可废弃的位图。应用程序可以通过一个DIB位图而创建一个DDB位图,只要先初始化一些必要的结构,然后再调用CreateDIBitmap()函数就可以。如果在调用该函数时指定了CBM_INIT标志,那么这一次调用就等价于先调用CreateCompati

12、bleBitmap()创建当前设备格式的DDB位图,然后又调用SetDIBits()函数转换DIB格式到DDB格式。(可能有些设备并不支持SetDIBits()函数,你可以指定RC_DI_BITMAP作为RASTERCAPS的标志,然后调用GetDeviceCaps()函数来判断一下)。对应的数据结构:1:BMP文件组成BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。2:BMP文件头(14字节)BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。其结构定义如下:typedef struct tagBITMAPFILEHEADERWORD bfType; / 位

13、图文件的类型,必须为BM(0-1字节)DWORD bfSize; / 位图文件的大小,以字节为单位(2-5字节)WORD bfReserved1; / 位图文件保留字,必须为0(6-7字节)WORD bfReserved2; / 位图文件保留字,必须为0(8-9字节)DWORD bfOffBits; / 位图数据的起始位置,以相对于位图(10-13字节)/ 文件头的偏移量表示,以字节为单位 BITMAPFILEHEADER;3:位图信息头(40字节)BMP位图信息头数据用于说明位图的尺寸等信息。typedef struct tagBITMAPINFOHEADERDWORD biSize; /

14、本结构所占用字节数(14-17字节)LONG biWidth; / 位图的宽度,以像素为单位(18-21字节)LONG biHeight; / 位图的高度,以像素为单位(22-25字节)WORD biPlanes; / 目标设备的级别,必须为1(26-27字节)WORD biBitCount;/ 每个像素所需的位数,必须是1(双色),(28-29字节)/ 4(16色),8(256色)或24(真彩色)之一DWORD biCompression; / 位图压缩类型,必须是 0(不压缩),(30-33字节)/ 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一DWORD biSizeIm

15、age; / 位图的大小,以字节为单位(34-37字节)LONG biXPelsPerMeter; / 位图水平分辨率,每米像素数(38-41字节)LONG biYPelsPerMeter; / 位图垂直分辨率,每米像素数(42-45字节)DWORD biClrUsed;/ 位图实际使用的颜色表中的颜色数(46-49字节)DWORD biClrImportant;/ 位图显示过程中重要的颜色数(50-53字节) BITMAPINFOHEADER;4:颜色表颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:typed

16、ef struct tagRGBQUAD BYTE rgbBlue;/ 蓝色的亮度(值范围为0-255)BYTE rgbGreen; / 绿色的亮度(值范围为0-255)BYTE rgbRed; / 红色的亮度(值范围为0-255)BYTE rgbReserved;/ 保留,必须为0 RGBQUAD;颜色表中RGBQUAD结构数据的个数有biBitCount来确定:当biBitCount=1,4,8时,分别有2,16,256个表项;当biBitCount=24时,没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:typedef struct tagBITMAPIN

17、FO BITMAPINFOHEADER bmiHeader; / 位图信息头RGBQUAD bmiColors1; / 颜色表 BITMAPINFO;5:位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节;Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,biSizeImage

18、= (bi.biWidth * bi.biBitCount) + 31) & 31) / 8) * bi.biHeight;具体数据举例:如某BMP文件开头:424D 4690 0000 0000 0000 4600 0000 2800 0000 8000 0000 9000 0000 0100*1000 0300 0000 0090 0000 A00F 0000 A00F 0000 0000 0000 0000 0000*00F8 0000 E007 0000 1F00 0000 0000 0000*02F1 84F1 04F1 84F1 84F1 06F2 84F1 06F2 04F2 8

19、6F2 06F2 86F2 86F2 . .BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。一、图像文件头1)1:(这里的数字代表的是字,即两个字节,下同)图像文件头。0x4D42=BM,表示是Windows支持的BMP格式。2)2-3:整个文件大小。4690 0000,为00009046h=36934。3)4-5:保留,必须设置为0。4)6-7:从文件开始到位图数据之间的偏移量。4600 0000,为00000046h=70,上面的文件头就是35字=70字节。二、位图信息头5)8-9:位图图信息头长度。6)10-11:位图宽度,以像素为单位。800

20、0 0000,为0000080h=128。7)12-13:位图高度,以像素为单位。9000 0000,为00000090h=144。8)14:位图的位面数,该值总是1。0100,为0001h=1。9)15:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。1000为0010h=16。10)16-17:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存

21、放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0300 0000为00000003h=3。11)18-19:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于(位图宽度的最小的4的倍数)位图高度每个像素位数。0090 0000为00009000h=80902h=36864。12)20-21:用象素/米表示的水平分辨率。A00F 0000为0000 0FA0h=4000。13)22-23:用象素/米表示的垂直分辨率。A00F 0000为0000 0FA0h=4000。14)24-25:位图使用的颜色索引数。设为0的话,则说明使用所有调色板项。15)26-27:对图象显示有

22、重要影响的颜色索引的数目。如果是0,表示都重要。三、彩色板16)28-.(不确定):彩色板规范。对于调色板中的每个表项,用下述方法来描述RGB的值:1字节用于蓝色分量1字节用于绿色分量1字节用于红色分量1字节用于填充符(设置为0)对于24-位真彩色图像就不使用彩色板,因为位图中的RGB值就代表了每个象素的颜色。如,彩色板为00F8 0000 E007 0000 1F00 0000 0000 0000,其中:00FB 0000为FB00h=1111100000000000(二进制),是蓝色分量的掩码。E007 0000为 07E0h=0000011111100000(二进制),是绿色分量的掩码。

23、1F00 0000为001Fh=0000000000011111(二进制),是红色分量的掩码。0000 0000总设置为0。将掩码跟像素值进行“与”运算再进行移位操作就可以得到各色分量值。看看掩码,就可以明白事实上在每个像素值的两个字节16位中,按从高到低取5、6、5位分别就是r、g、b分量值。取出分量值后把r、g、b值分别乘以8、4、8就可以补齐第个分量为一个字节,再把这三个字节按rgb组合,放入存储器(同样要反序),就可以转换为24位标准BMP格式了。四、图像数据阵列17)27(无调色板)-:每两个字节表示一个像素。阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素

24、。五、存储算法BMP文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多。例如,一个800600的24位几乎占据1.4MB空间。因此它们通常不适合在因特网或者其它低速或者有容量限制的媒介上进行传输。 根据颜色深度的不同,图像上的一个像素可以用一个或者多个字节表示,它由n/8所确定(n是位深度,1字节包含8个数据位)。图片浏览器等基于字节的ASCII值计算像素的颜色,然后从调色板中读出相应的值。更为详细的信息请参阅下面关于位图文件的部分。 n位2n种颜色的位图近似字节数可以用下面的公式计算: BMP文件大小约等于 54+4*2的n次方+(w*h*n)/8,其中高度和宽度都是像素

25、数。 需要注意的是上面公式中的54是位图文件的文件头,是彩色调色板的大小。另外需要注意的是这是一个近似值,对于n位的位图图像来说,尽管可能有最多2n中颜色,一个特定的图像可能并不会使用这些所有的颜色。由于彩色调色板仅仅定义了图像所用的颜色,所以实际的彩色调色板将小于。 如果想知道这些值是如何得到的,请参考下面文件格式的部分。 由于存储算法本身决定的因素,根据几个图像参数的不同计算出的大小与实际的文件大小将会有一些细小的差别。VB函数窗口截图保存,支持窗口遮挡,一样可以截图保存。以下函数放在标准模块中即可以调用使用。Option ExplicitPrivate Const BI_RGB = 0&

26、Private Const DIB_RGB_COLORS = 0Private Const OBJ_BITMAP As Long = 7Private Type RECT Left As Long Top As Long Right As Long Bottom As LongEnd TypePrivate Type BITMAPINFOHEADER biSize As Long biWidth As Long biHeight As Long biPlanes As Integer biBitCount As Integer biCompression As Long biSizeImage

27、 As Long biXPelsPerMeter As Long biYPelsPerMeter As Long biClrUsed As Long biClrImportant As LongEnd TypePrivate Type BITMAPINFO bmiHeader As BITMAPINFOHEADER bmiColors As RGBQUADEnd TypePrivate bi24BitInfo As BITMAPINFOPrivate aBytes() As BytePrivate Declare Function GetCurrentObject Lib gdi32.dll

28、_ (ByVal hdc As Long, ByVal uObjectType As Long) As LongPrivate Declare Function GetDIBits Lib gdi32 _ (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As LongPrivate Declare Function GetWindowRect

29、 Lib user32.dll _ (ByVal Hwnd As Long, ByRef lpRect As RECT) As LongPrivate Declare Function DeleteObject Lib gdi32 _ (ByVal hObject As Long) As LongPrivate Declare Function PrintWindow Lib user32 _ (ByVal Hwnd As Long, ByVal hdcBlt As Long, ByVal nFlags As Long) As LongPrivate Declare Function Sele

30、ctObject Lib gdi32 _ (ByVal hdc As Long, ByVal hObject As Long) As LongPrivate Declare Function GetDC Lib user32 (ByVal Hwnd As Long) As LongPrivate Declare Function CreateCompatibleDC Lib gdi32 (ByVal hdc As Long) As LongPrivate Declare Function DeleteDC Lib gdi32 (ByVal hdc As Long) As LongPrivate

31、 Declare Function CreateCompatibleBitmap Lib gdi32 _ (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long*以上是API申明部分以及BMP文件头定义等*Public Function BSavePic(ByVal Hwnd As Variant, PathFile As Variant) As Long 后台截图,参数1要截图的窗口句柄,参数2要保存的文件路径 Dim hWndTarget As Long Dim rc As RECT Dim iBit

32、map As Long Dim mDC As Long, nDC As Long Dim mBmp As Long Dim oldBmp As Long Dim W As Long, H As Long, Bmplen As Long, R As Long Dim BMPbyte(53) As Byte hWndTarget = Hwnd If hWndTarget = 0 Then BSavePic = 0 Exit Function End If GetWindowRect hWndTarget, rc 得到句柄窗口的矩形位置,大小 If (rc.Right - rc.Left) Mod

33、4 0 Then W = rc.Right - rc.Left - (rc.Right - rc.Left) Mod 4) + 4 Else W = rc.Right - rc.Left End If H = rc.Bottom - rc.Top With bi24BitInfo.bmiHeader 初始化24位BMP信息头 .biBitCount = 24 .biCompression = BI_RGB .biPlanes = 1 .biSize = Len(bi24BitInfo.bmiHeader) .biWidth = W .biHeight = H .biSizeImage = W

34、* H * 3 End With Bmplen = W * H * 3 + 54 *以下初始化BMP文件头信息到字节数组*文件头 + 位图信息 + 位图像素数据* BMPbyte(0) = 66 BMPbyte(1) = 77 CopyMemory BMPbyte(2), Bmplen, 4 bfSize As Long文件长 2-5 CopyMemory BMPbyte(6), 0, 4 bfReserved1,2 As Integer 6-9 CopyMemory BMPbyte(10), 54, 4 bfOffBits As Long 10-13 以上文件头* CopyMemory BM

35、Pbyte(14), bi24BitInfo.bmiHeader.biSize, 4 biSize As Long 14-17 CopyMemory BMPbyte(18), bi24BitInfo.bmiHeader.biWidth, 4 biWidth As Long 18-21 CopyMemory BMPbyte(22), bi24BitInfo.bmiHeader.biHeight, 4 biHeight As Long 22-25 CopyMemory BMPbyte(26), bi24BitInfo.bmiHeader.biPlanes, 2 biPlanes As Intege

36、r 26-27 CopyMemory BMPbyte(28), 24, 2 biBitCount As Integer 28-29,真彩24位色 CopyMemory BMPbyte(30), bi24BitInfo.bmiHeader.biCompression, 4 biCompression As Long 30-33 CopyMemory BMPbyte(34), bi24BitInfo.bmiHeader.biSizeImage, 4 biSizeImage As Long 34-37 CopyMemory BMPbyte(38), bi24BitInfo.bmiHeader.biX

37、PelsPerMeter, 4 biXPelsPerMeter As Long 38-41 For R = 38 To 53 BMPbyte(R) = 0 Next 以上写位图信息*On Error Resume Next nDC = GetDC(hWndTarget) 得到指定窗口句柄DC mDC = CreateCompatibleDC(nDC) 创建内存DC mBmp = CreateCompatibleBitmap(nDC, W, H) oldBmp = SelectObject(mDC, mBmp) 把窗口位图选入内存DC PrintWindow hWndTarget, mDC, 0

38、 把窗口截取保存到内存DC中, ReDim aBytes(0 To W * H * 3 - 1) As Byte iBitmap = GetCurrentObject(mDC, OBJ_BITMAP) 用于获得指定类型的当前选定对象 GetDIBits mDC, iBitmap, 0, H, aBytes(0), bi24BitInfo, DIB_RGB_COLORS Open PathFile For Binary As #1 Put #1, , BMPbyte() Put #1, , aBytes() Close #1 DeleteObject iBitmap DeleteObject mBmp DeleteObject oldBmp DeleteDC mDC DeleteDC nDC Erase aBytes BSavePic = 1End Function

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号