你可以这样读取BMP文件:
Open BmpFileName For Binary Access Read As #1
Get #1, , bmHead
Get #1, , bmInfo
Get #1, , bmPalatte
ww = bmInfo.biWidth
hh = bmInfo.biHeight
ww1 = Fix((ww + 3) / 4) * 4
ReDim image(ww1 - 1, hh - 1) As Byte
Get #1, , image
Close #1nPixels = CLng(w) * h
Open BmpFileName For Binary Access Read As #1
Get #1, , bmHead
Get #1, , bmInfo
Get #1, , bmPalatte
ww = bmInfo.biWidth
hh = bmInfo.biHeight
ww1 = Fix((ww + 3) / 4) * 4
ReDim image(ww1 - 1, hh - 1) As Byte
Get #1, , image
Close #1nPixels = CLng(w) * h
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
2. BMP文件头
BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 其结构定义如下: typedef struct tagBITMAPFILEHEADER
{
WORDbfType; // 位图文件的类型,必须为BM
DWORD bfSize; // 位图文件的大小,以字节为单位
WORDbfReserved1; // 位图文件保留字,必须为0
WORDbfReserved2; // 位图文件保留字,必须为0
DWORD bfOffBits; // 位图数据的起始位置,以相对于位图
// 文件头的偏移量表示,以字节为单位
} BITMAPFILEHEADER;3. 位图信息头 BMP位图信息头数据用于说明位图的尺寸等信息。
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // 本结构所占用字节数
LONGbiWidth; // 位图的宽度,以像素为单位
LONGbiHeight; // 位图的高度,以像素为单位
WORD biPlanes; // 目标设备的级别,必须为1
WORD biBitCount// 每个像素所需的位数,必须是1(双色),
// 4(16色),8(256色)或24(真彩色)之一
DWORD biCompression; // 位图压缩类型,必须是 0(不压缩),
// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORD biSizeImage; // 位图的大小,以字节为单位
LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数
DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数
DWORD biClrImportant;// 位图显示过程中重要的颜色数
} BITMAPINFOHEADER;4. 颜色表
颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
BYTErgbGreen; // 绿色的亮度(值范围为0-255)
BYTErgbRed; // 红色的亮度(值范围为0-255)
BYTErgbReserved;// 保留,必须为0
} RGBQUAD;
颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
当biBitCount=1,4,8时,分别有2,16,256个表项;
当biBitCount=24时,没有颜色表项。
位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 颜色表
} BITMAPINFO;
5. 位图数据
位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数: 当biBitCount=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是
4的倍数(即以long为单位),不足的以0填充,
一个扫描行所占的字节数计算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;
// 一个扫描行所占的字节数
DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
位图数据的大小(不压缩情况下):
DataSize= DataSizePerLine* biHeight;
'
'Within a bitmap file are 2 header groupings of information describing the bitmap image in that file. This data is contained in the file's BITMAPFILEHEADER and BITMAPINFOHEADER structures. By using the VB Type to recreate these structures, the details of the bitmap contained in the file can be obtained with a simple binary read of this data.
'(Note: due to the formatting of the code to allow pasting into VB, the strings used here will necessitate horizontal scrolling of the browser window on displays under 1024x768 full screen.)
'
'
' Form Code
'
'To a form add the controls as indicated in the illustration. To see a template of this form with control names substituted for the control captions, click here to open the image in a new window.
'
'The names of the description labels is unimportant, but the data returned from the routine below posts the information to the lblInfo() label array. Also on the form is an image control (Image1), with its Stretch property set to True, two command buttons (cmdSelect and cmdEnd), and another label to contain the selected filename and path (lblFileName). Finally, the routine needs a common dialog control (CMDialog1) added to the form.
'
'Paste the following code into the general declarations section of the form:'--------------------------------------------------------------------------------
Option Explicit Private Const CANCELERR = 32755
Private Const BI_RGB = 0&
Private Const BI_RLE8 = 1&
Private Const BI_RLE4 = 2&
Private Const BI_BITFIELDS = 3&
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type BITMAPFILEHEADER
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
Private Sub Form_Load()
'initialize the form controls
lblFileName = "Select a bitmap or RLE file to detail..."
lblInfo(0) = ""
lblInfo(1) = ""
lblInfo(2) = ""
lblInfo(3) = ""
lblInfo(4) = ""
lblInfo(5) = ""
lblInfo(6) = ""
lblInfo(7) = ""
'position the form
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2End Sub
Private Sub cmdEnd_Click() Unload MeEnd Sub
Private Sub cmdSelect_Click()
'create some working variables
Dim ff As Integer
Dim tmp As String
'create the variables to hold the bitmap info
Dim FileHeader As BITMAPFILEHEADER
Dim InfoHeader As BITMAPINFOHEADER On Error GoTo cmdSelect_FileErrorHandler
'show the common dialog
CMDialog1.CancelError = True
CMDialog1.ShowOpen
'display a rendition of the loaded bitmap
Image1 = LoadPicture((CMDialog1.filename))
Image1.ZOrder 1
'read the file header info
ff = FreeFile
Open CMDialog1.filename For Binary Access Read As #ff
Get #ff, , FileHeader
Get #ff, , InfoHeader
Close #ff
'display the file info
lblFileName = CMDialog1.filename
lblInfo(0) = InfoHeader.biWidth & " pixels"
lblInfo(1) = InfoHeader.biHeight & " pixels"
'select the appropriate string based on the value of biCompression
Select Case InfoHeader.biSizeImage
Case 0: tmp$ = "BI_RGB bitmap; size variable not filled in."
Case Else: tmp$ = Format$(InfoHeader.biSizeImage, "#,###,###") & " bytes"
End Select
lblInfo(2) = tmp$
lblInfo(3) = InfoHeader.biPlanes
lblInfo(4) = InfoHeader.biBitCount & " (" & 2 ^ InfoHeader.biBitCount & " colours)" 'select the appropriate string based on the value of biCompression
Select Case InfoHeader.biCompression
Case BI_RGB: tmp$ = "Uncompressed bitmap."
Case BI_RLE8: tmp$ = "Run-length encoded (RLE) format for bitmaps with 8 bits per pixel."
Case BI_RLE4: tmp$ = "Run-length encoded (RLE) format for bitmaps with 4 bits per pixel."
Case BI_BITFIELDS: tmp$ = "Uncompressed 16- or 32-bit-per-pixel format."
End Select
lblInfo(5) = tmp$ 'select the appropriate string based on the value of biClrUsed
Select Case InfoHeader.biClrUsed
Case 0:
tmp$ = "Bitmap uses the maximum number of colours corresponding to the"
tmp$ = tmp$ & " bits-per-pixel for the compression mode." Case Is <> 0 And InfoHeader.biBitCount = 16:
tmp$ = "The size of the colour table used to optimize performance"
tmp$ = tmp$ & "of Windows colour palettes is " & Str$(InfoHeader.biClrUsed)
End Select
lblInfo(6) = tmp$
'select the appropriate string based on the value of biClrImportant
Select Case InfoHeader.biClrImportant
Case 0:
tmp$ = "All " & 2 ^ InfoHeader.biBitCount & " colour"
tmp$ = tmp$ & " indices are considered important for displaying this bitmap."
Case Is <> 0
tmp$ = "The number of colours that are considered important for displaying"
tmp$ = tmp$ & " this bitmap are " & Str$(InfoHeader.biClrImportant)
End Select
lblInfo(7) = tmp$
Exit Sub'handle file errors or the user choosing cancel
cmdSelect_FileErrorHandler: If Err <> CANCELERR Then MsgBox Error$(Err), 48, "Image Info"
lblFileName = "No file was selected."End Sub
我用savepicture方法保存一副图,可保存的结果是:不仅大小和原图不一样比原图大了不少,而且保存图的宽度和高度也和原图不一样。这是怎么回事呢?
请指教!!!
Option Explicit
Private Declare Function SetPixelV Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As LongPublic Type ZMapInfoType
Headle As Integer
MapType As String * 3
MapCount As Integer
End TypePrivate Type BitMapAllHeader
bfType As String * 2
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
'---------------------
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXRes As Long
biYRes As Long
biClrUsed As Long
biClrImportant As Long
End TypePrivate Type BitMapPalette
peBlue As Byte
peGreen As Byte
peRed As Byte
peFlags As Byte
End TypePublic Sub ChkMapType(MapInfo As ZMapInfoType)
Dim LoadByt() As Byte
ReDim LoadByt(0 To 1) As Byte
Get MapInfo.Headle, 1, LoadByt
If UCase$(StrConv(LoadByt, vbUnicode)) = "BM" Then
MapInfo.MapType = "BMP"
Else
MapInfo.MapType = ""
End If
End SubPublic Function GetMapCount(MapInfo As ZMapInfoType) As Integer
Select Case UCase$(RTrim$(MapInfo.MapType))
Case "BMP"
MapInfo.MapCount = 1
Case Else
MapInfo.MapCount = 0
End Select
GetMapCount = MapInfo.MapCount
End FunctionPublic Function GetMapSize(MapInfo As ZMapInfoType, _
Width As Long, _
Height As Long, _
Optional MapIndex As Integer) As Integer
On Error GoTo LoadErr
Select Case UCase$(RTrim$(MapInfo.MapType))
Case "BMP"
'MapInfo.MapCount = 1
Dim BMah As BitMapAllHeader
Get MapInfo.Headle, 1, BMah
Width = BMah.biWidth
Height = BMah.biHeight
Case Else
On Error GoTo 0
GetMapSize = 0: Exit Function
End Select
On Error GoTo 0
GetMapSize = -1
Exit Function
LoadErr:
GetMapSize = 0
End FunctionPublic Function LoadBmpMap(hDC As Long, _
PutX As Long, PutY As Long, _
MapInfo As ZMapInfoType, _
FileX As Long, FileY As Long, _
ByVal FileWidth As Long, ByVal FileHeight As Long) As Integer
Dim Width As Long, Height As Long
Dim I As Long, J As Long, K As Long
Dim BMah As BitMapAllHeader
Dim LoadPalette As BitMapPalette
Dim LoadByt1 As Byte, LoadByt() As Byte
Dim BMPPalette(0 To 255) As Long
Dim PutColor As Long
Dim LineByt As Long
If FileX + FileWidth <= 0 Or FileY + FileHeight <= 0 Then GoTo LoadErr
On Error GoTo LoadErr
Get MapInfo.Headle, 1, BMah
If BMah.biPlanes <> 1 Or BMah.biCompression <> 0 Then LoadBmpMap = 1: Exit Function
Width = BMah.biWidth
Height = BMah.biHeight
If FileX + FileWidth > Width Then FileWidth = Width - FileX
If FileY + FileHeight > Height Then FileHeight = Height - FileY
'Debug.Print FileX, FileWidth, PutX, Width
'Debug.Print FileY, FileHeight, PutY, Height
Select Case BMah.biBitCount
Case 24
'Get MapInfo.Headle, BMah.bfOffBits, LoadByt1
LineByt = Int((Width * 3 + 3) / 4) * 4
ReDim LoadByt(0 To FileWidth * 3 - 1) As Byte
For I = 0 To FileHeight - 1
'Get MapInfo.Headle, BMah.bfOffBits + LineByt * (Height - (I + FileY) - 1) + FileX * 3, LoadByt1
Get MapInfo.Headle, BMah.bfOffBits + LineByt * (Height - (I + FileY) - 1) + FileX * 3 + 1, LoadByt
For J = 0 To FileWidth - 1
PutColor = 0
For K = 0 To 2
'Get MapInfo.Headle, , LoadByt1
LoadByt1 = LoadByt(J * 3 + K)
PutColor = PutColor Or LoadByt1 * &H100& ^ (2 - K)
Next K
SetPixelV hDC, J + PutX, I + PutY, PutColor
Next J
Next I
Case 8
For I = 0 To 255
Get MapInfo.Headle, , LoadPalette
BMPPalette(I) = RGB(LoadPalette.peRed, LoadPalette.peGreen, LoadPalette.peBlue)
Next I
LineByt = Int((Width + 3) / 4) * 4
ReDim LoadByt(0 To FileWidth - 1) As Byte
For I = 0 To FileHeight - 1
Get MapInfo.Headle, BMah.bfOffBits + LineByt * (Height - (I + FileY) - 1) + FileX + 1, LoadByt
For J = 0 To FileWidth - 1
SetPixelV hDC, J + PutX, I + PutY, BMPPalette(LoadByt(J))
Next J
Next I
Case 4
For I = 0 To 16
Get MapInfo.Headle, , LoadPalette
BMPPalette(I) = RGB(LoadPalette.peRed, LoadPalette.peGreen, LoadPalette.peBlue)
Next I
LineByt = Int((Int((Width + 1) / 2) + 3) / 4) * 4
ReDim LoadByt(0 To Int((Width + 1) / 2) - 1) As Byte
For I = 0 To FileHeight - 1
Get MapInfo.Headle, BMah.bfOffBits + LineByt * (Height - (I + FileY) - 1) + 1, LoadByt
For J = 0 To FileWidth - 1 Step 2
SetPixelV hDC, J + PutX, I + PutY, BMPPalette((LoadByt(Int(J / 2)) And &HF0) \ &H10)
SetPixelV hDC, J + PutX + 1, I + PutY, BMPPalette(LoadByt(Int(J / 2)) And &HF)
Next J
Next I
Case 1
Dim BitAnd(0 To 15) As Integer
For I = 0 To 7
BitAnd(I) = 2 ^ (7 - I)
Next I
BitAnd(8) = &H8000
For I = 0 To 6
BitAnd(9 + I) = 2 ^ (14 - I)
Next I
For I = 0 To 1
Get MapInfo.Headle, , LoadPalette
BMPPalette(I) = RGB(LoadPalette.peRed, LoadPalette.peGreen, LoadPalette.peBlue)
Next I
LineByt = Int((Int((Width + 7) / 8) + 3) / 4) * 4
ReDim LoadByt(0 To Int((Width + 7) / 8) - 1) As Byte
For I = 0 To FileHeight - 1
Get MapInfo.Headle, BMah.bfOffBits + LineByt * (Height - (I + FileY) - 1) + 1, LoadByt
For J = 0 To FileWidth - 1 Step 8
For K = 0 To 7
SetPixelV hDC, J + PutX + K, I + PutY, BMPPalette((((LoadByt(Int(J / 8)) And BitAnd(K)) <> 0) And 1))
Next K
Next J
Next I
Case Else
LoadBmpMap = 2
Exit Function
End Select
On Error GoTo 0
LoadBmpMap = 0
Exit Function
LoadErr:
LoadBmpMap = -1
End Function
Private Sub LoadBMPSub()
Dim ZMap As ZMapInfoType
Dim Wi As Long, He As Long
If ChkFileRead(Text1.Text) = False Then Exit Sub
ZMap.Headle = FreeFile
Open Text1.Text For Binary As ZMap.Headle
Me.MousePointer = 11
Me.Caption = MeName + " (Loading)"
ChkMapType ZMap
If GetMapCount(ZMap) = 0 Then Exit Sub
If GetMapSize(ZMap, Wi, He) = 0 Then Exit Sub
SetSize Pic2, Wi, He
DoEvents
LoadBmpMap Pic2.hDC, 0, 0, ZMap, 0, 0, Wi, He
Me.MousePointer = 0
Me.Caption = MeName
Close ZMap.Headle
Pic2.Picture = Pic2.Image
JSS
End Sub
32*32代表什么意思?
如用数组来保存它,那么这个二维数组要有多大?
谢谢