将图片导入Excel背景...纯娱乐

只对应了24位深,测试通过,巨卡的...

Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Type BITMAPFILEHEADER  'this struct's size: 14byte
    bfType As Integer 'must be "BM"
    bfSize As Long 'bmp file size in bytes
    bfReserved1 As Integer 'reserved must be 0
    bfReserved2 As Integer 'reserved must be 0
    bfOffBits As Long 'pic data start pos from 0?
End Type

Private Type BITMAPINFOHEADER 'struct size:40 byte
    biSize As Long 'this struct's size in byte (40)
    biWidth As Long 'picture width in pix
    biHeight As Long 'picture height in pix
    biPlanes As Integer 'must be 1
    biBitCount As Integer 'bit count per pix. mustbe in 1(mono)/4(16color)/8(256color)/24(full color)
    biCompression As Long 'picture compress type. mustbe in 0(no compress)/1(BI_RLE8 compress)/2(BI_RLE4 compress)
    biSizeImage As Long 'picture size in bytes
    biXPelsPerMeter As Long 'pix count per meter V
    biYPelsPerMeter As Long 'pix count per meter H
    biClrUsed As Long 'used color count in color table
    biClrImportant As Long 'important color count in display
End Type

Private Type MY_BMP_HEAD
    file_header As BITMAPFILEHEADER
    bmp_header As BITMAPINFOHEADER
End Type
Public gBM As MY_BMP_HEAD
Public gOrigBmpData() As Byte

Sub readBinFile(ByVal fn$, ByRef gOrigBmpData() As Byte, ByRef outBinDataLen&)
    Open fn For Binary As #1
    outBinDataLen = FileLen(fn)
    ReDim gOrigBmpData(0 To outBinDataLen - 1) As Byte
    Get #1, , gOrigBmpData
    Close #1
End Sub

Sub tessss()
    Dim dataLen&, sh As Worksheet
    Dim need_y As Long, y&
    
    Call readBinFile("E:\maxw\study\gitee\misc\bmpparser\BmpParser\bmp_files\splash_bit24_452x302.bmp", gOrigBmpData, dataLen)
    'Set sh = Sheets.Add(, Sheets(Sheets.Count))
    Set sh = Sheets("pic")
    Cells.Interior.Pattern = xlNone
    sh.Cells.ColumnWidth = 0.06 '* 10
    sh.Cells.RowHeight = 0.6 '* 10
    
    CopyMemory gBM.file_header.bfType, gOrigBmpData(0), 2 'cause of vb can not using like #pragma pack in c
    CopyMemory gBM.file_header.bfSize, gOrigBmpData(2), 12 + 40
    need_y = gBM.bmp_header.biHeight 'gBmpOutputHei > gBM.bmp_header.biHeight ? gBM.bmp_header.biHeight : gBmpOutputHei;
    For y = 0 To need_y - 1
        Call proc1row(y)
    Next
End Sub

Sub proc1row(ByVal y&)
    Dim pOrigIdx&, needWid&, rgb&, r As Byte, g As Byte, b As Byte, x&
    pOrigIdx = get_data_buf_header_by_row(y)
    needWid = gBM.bmp_header.biWidth 'gBmpOutputWid > gBM.bmp_header.biWidth ? gBM.bmp_header.biWidth : gBmpOutputWid;
    For x = 0 To needWid - 1
        rgb = get_1RGB(pOrigIdx, x, r, g, b)
        Cells(y + 1, x + 1).Interior.Color = VBA.rgb(r, g, b)
    Next
End Sub

Function get_data_buf_header_by_row(ByVal r&) As Long '//r:row: start@0
    Dim row_byte_len&, offset&
    row_byte_len = get_byte_cnt_per_row(gBM.bmp_header.biBitCount, gBM.bmp_header.biWidth)
    offset = 0
    If (gBM.bmp_header.biHeight > 0) Then '{//正?表示数据倒向排列
        offset = row_byte_len * (gBM.bmp_header.biHeight - r - 1)
    Else
        offset = row_byte_len * r
    End If
    get_data_buf_header_by_row = offset
End Function


Function get_byte_cnt_per_row(ByVal bitCount&, ByVal wid&) As Long
    Dim row_byte_cnt&, yu& '; //?行占用的byte数
    row_byte_cnt = 0
    Select Case bitCount
    Case 1
        row_byte_cnt = (wid + 7) / 8 '; //?8个pix占用一个byte
    Case 4
        row_byte_cnt = (wid + 1) / 2 '; //?2个pix占用一个byte
    Case 8
        row_byte_cnt = wid '; //?1个pix占用一个byte
    Case 24
        row_byte_cnt = wid * 3 '; //?1个pix占用3个byte
    Case Else
        row_byte_cnt = 0 ';
    End Select
    
    yu = row_byte_cnt Mod 4
    If yu <> 0 Then '; //align with 4
        row_byte_cnt = row_byte_cnt + (4 - yu)
    End If
    'row_byte_cnt = (CInt((row_byte_cnt + 3) / 4)) * 4
    get_byte_cnt_per_row = row_byte_cnt
End Function

Function get_1RGB(ByVal buf_line_headerIDX, ByVal x&, ByRef r As Byte, ByRef g As Byte, ByRef b As Byte) As Long '//col_idx:start@0
    Dim div&, modV&, ret&, color_tab_idx&

    get_1RGB = 0
    'RGBQUAD* pt = (RGBQUAD*)gColorTbl.buf;
    Select Case (gBM.bmp_header.biBitCount)
    Case 1
        div = x / 8
        modV = x Mod 8
        modV = 7 - modV '; //reverse
        'color_tab_idx = ((buf_line_headerIDX[div] >> modV) & 0x1);
        'ret = RGB(pt[color_tab_idx].rgbRed, pt[color_tab_idx].rgbGreen, pt[color_tab_idx].rgbBlue);
        'break;
    Case 4:
     '   div = x / 2;
      '  modV = x % 2;
       ' modV = 1 - modV; //reverse
        'color_tab_idx = ((buf_line_headerIDX[div] >> (modV * 4)) & 0xF);
        'ret = RGB(pt[color_tab_idx].rgbRed, pt[color_tab_idx].rgbGreen, pt[color_tab_idx].rgbBlue);
        'break;
    Case 8:
        'color_tab_idx = buf_line_headerIDX[x];
        'color_tab_idx &= 0xFF;
        'ret = RGB(pt[color_tab_idx].rgbRed, pt[color_tab_idx].rgbGreen, pt[color_tab_idx].rgbBlue);
        'break;
    Case 24:
        'ret = RGB(buf_line_headerIDX[x * 3 + 2], buf_line_headerIDX[x * 3 + 1], buf_line_headerIDX[x * 3])
        r = gOrigBmpData(buf_line_headerIDX + x * 3 + 2)
        g = gOrigBmpData(buf_line_headerIDX + x * 3 + 1)
        b = gOrigBmpData(buf_line_headerIDX + x * 3)
    Case Else
        ret = 0
    End Select
    get_1RGB = ret
End Function

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值