你可以这样读取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

解决方案 »

  1.   

    bmp 文 件     bmp(bitmap 的 缩 写) 文 件 格 式 是 windows 本 身 的 位 图 文 件 格 式, 所 谓 本 身 是 指 windows 内 部 存 储 位 图 即 采 用 这 种 格 式。 一 个 .bmp 格 式 的 文 件 通 常 有 .bmp 的 扩 展 名, 但 有 一 些 是 以 .rle 为 扩 展 名 的, rle 的 意 思 是 行 程 长 度 编 码(run length encoding)。 这 样 的 文 件 意 味 着 其 使 用 的 数 据 压 缩 方 法 是 .bmp 格 式 文 件 支 持 的 两 种 rle 方 法 中 的 一 种。     bmp 文 件 可 用 每 象 素 1、 4、 8、 16 或 24 位 来 编 码 颜 色 信 息, 这 个 位 数 称 作 图 象 的 颜 色 深 度, 它 决 定 了 图 象 所 含 的 最 大 颜 色 数。 一 幅 1-bpp(位 每 象 素, bit per pixel) 的 图 象 只 能 有 两 种 颜 色。 而 一 幅 24-bpp 的 图 象 可 以 有 超 过 16 兆 种 不 同 的 颜 色。     下 一 页 的 图 说 明 了 一 个 典 型 .bmp 文 件 的 结 构。 它 是 以 256 色 也 就 是 8-bpp 为 例 的, 文 件 被 分 成 四 个 主 要 的 部 分: 一 个 位 图 文 件 头, 一 个 位 图 信 息 头, 一 个 色 表 和 位 图 数 据 本 身。 位 图 文 件 头 包 含 关 于 这 个 文 件 的 信 息。 如 从 哪 里 开 始 是 位 图 数 据 的 定 位 信 息, 位 图 信 息 头 含 有 关 于 这 幅 图 象 的 信 息, 例 如 以 象 素 为 单 位 的 宽 度 和 高 度。 色 表 中 有 图 象 颜 色 的 rgb 值。 对 显 示 卡 来 说, 如 果 它 不 能 一 次 显 示 超 过 256 种 颜 色, 读 取 和 显 示 .bmp 文 件 的 程 序 能 够 把 这 些 rgb 值 转 换 到 显 示 卡 的 调 色 板 来 产 生 准 确 的 颜 色。     bmp 文 件 的 位 图 数 据 格 式 依 赖 于 编 码 每 个 象 素 颜 色 所 用 的 位 数。 对 于 一 个 256 色 的 图 象 来 说, 每 个 象 素 占 用 文 件 中 位 图 数 据 部 分 的 一 个 字 节。 象 素 的 值 不 是 rgb 颜 色 值, 而 是 文 件 中 色 表 的 一 个 索 引。 所 以 在 色 表 中 如 果 第 一 个 r/g/b 值 是 255/0/0, 那 么 象 素 值 为 0 表 示 它 是 鲜 红 色, 象 素 值 按 从 左 到 右 的 顺 序 存 储, 通 常 从 最 后 一 行 开 始。 所 以 在 一 个 256 色 的 文 件 中, 位 图 数 据 中 第 一 个 字 节 就 是 图 象 左 下 角 的 象 素 的 颜 色 索 引, 第 二 个 就 是 它 右 边 的 那 个 象 素 的 颜 色 索 引。 如 果 位 图 数 据 中 每 行 的 字 节 数 是 奇 数, 就 要 在 每 行 都 加 一 个 附 加 的 字 节 来 调 整 位 图 数 据 边 界 为 16 位 的 整 数 倍。     并 不 是 所 有 的 bmp 文 件 结 构 都 象 表 中 所 列 的 那 样, 例 如 16 和 24-bpp, 文 件 就 没 有 色 表, 象 素 值 直 接 表 示 rgb 值, 另 外 文 件 私 有 部 分 的 内 部 存 储 格 式 也 是 可 以 变 化 的。 例 如, 在 16 和 256 色 .bmp 文 件 中 的 位 图 数 据 采 用 rle 算 法 来 压 缩, 这 种 算 法 用 颜 色 加 象 素 个 数 来 取 代 一 串 颜 色 相 同 的 序 列, 而 且, windows 还 支 持 os/2 下 的 .bmp 文 件, 尽 管 它 使 用 了 不 同 的 位 图 信 息 头 和 色 表 格 式。 
      

  2.   

    1. BMP文件组成 
    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;
      

  3.   

    'The Bitmap Info project demonstrates one means of obtaining from a bitmap file on the disk its image information without loading the actual bitmap.
    '
    '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
      

  4.   

    一个奇怪的现象:
    我用savepicture方法保存一副图,可保存的结果是:不仅大小和原图不一样比原图大了不少,而且保存图的宽度和高度也和原图不一样。这是怎么回事呢?
    请指教!!!
      

  5.   

    关于BMP文件的格式可参考机械工业出版社出版的《Win32开发人员参考库(第三卷)》,里面有非常详细的描述。另外对于spirit2001(巍巍)的问题:BMP文件的宽度必须确保32位的字长,所以必须能被4整除。由于这个原因,BMP实际的宽度与图片宽度有差别的。但读出来显示的时候却是准确的宽度。
      

  6.   

    我曾经写过一个读取BMP的模块:
    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
      

  7.   

    使用方法:
    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
      

  8.   

    我们有时候说某张BMP图为32*32的图是什么意思?
    32*32代表什么意思?
    如用数组来保存它,那么这个二维数组要有多大?
    谢谢