如何使用 GetDIBits 将一幅图片导入字节数组?我的代码如下:(API 及 常量 申明忽略)VB code读入图片Dim hW
如何使用 GetDIBits 将一幅图片导入字节数组?
我的代码如下:
(API 及 常量 申明忽略)
- VB code
'读入图片 Dim hWndSmallAs Long hWndSmall = LoadImage(ByVal 0&, App.Path & "test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE) '获取图片长、宽 Dim picInfo As BITMAP Dim R As Long R = GetObject(hWndSmall, Len(picInfo), picInfo) Dim iWidthSmall As Long Dim iHeightSmall As Long iWidthSmall = picInfo.bmWidth iHeightSmall = picInfo.bmHeight MsgBox "图片宽度:" & iWidthSmall MsgBox "图片高度:" & iHeightSmall '创建兼容设备场景 Dim mDcSmall As Long mDcSmall = CreateCompatibleDC(0) '选入设备场景 SelectObject mDcSmall, hWndSmall Dim bi24BitInfoSmall As BITMAPINFO With bi24BitInfoSmall.bmiHeader .biBitCount = 24 .biCompression = BI_RGB .biPlanes = 1 .biSize = Len(bi24BitInfoSmall.bmiHeader) .biWidth = iWidthSmall .biHeight = -iHeightSmall End With Dim byteArraySmall() As Byte ReDim byteArraySmall(1 To iWidthSmall * iHeightSmall * 3) As Byte Dim iDCSmall As Long iDCSmall = CreateCompatibleDC(mDcSmall) Dim iBitmapSmall As Long iBitmapSmall = CreateDIBSection(iDCSmall, bi24BitInfoSmall, 0, ByVal 0&, ByVal 0&, ByVal 0&) SelectObject iDCSmall, iBitmapSmall BitBlt iDCSmall, 0, 0, iWidthSmall, iHeightSmall, mDcSmall, 0, 0, vbSrcCopy 'MsgBox "第一个点:" & CStr(GetPixel(iDCSmall, 0, 0)) '这一句就出错了,整个 VB 退出 GetDIBits iDCSmall, iBitmapSmall, 0, iHeightSmall, byteArraySmall(1), bi24BitInfoSmall, 0 MsgBox "ko"
[解决办法]
dib 是4字节对齐的,即每行字节数必须是4的倍数,所以你 iWidthSmall * iHeightSmall * 3 这个缓冲区的长度小了,getdibits的时候数据写出数组了,写到不该写的内存就崩溃了。
[解决办法]
发表两点看法:
1、楼主代码的问题确实是扫描行对齐问题
2、楼主的代码太冗余了。
阐述若干意见:
1、从代码上你的目的就是要获得图像的像素颜色值数据,有两个更好的方法,第一是picInfo这个结构体的bmBits 数值就是你加载的这幅图像在内存中的首地址,该地址后bmWidthBytes *bmHeight 个字节就是你的图像数据。第二还是用GetDIBits ,但是不需要后面那些函数了,直接用hWndSmall 作为GetDIBits 的第二个参数。
至于你看例子里面那个8*3不会错是因为一般屏幕的宽度恰好是4的倍数。
实际上这个来例子害人不浅。
[解决办法]
肯定是你参数调用不正确
Private Sub Command1_Click()
Dim Bmp As Bitmap
Dim Handle As Long
Dim Stride As Long
Handle = LoadImage(ByVal 0&, App.Path & "\Test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
GetObject Handle, Len(Bmp), Bmp
Dim BmpInfo As BITMAPINFO
With BmpInfo.bmiHeader
.biBitCount = 24
.biHeight = -Bmp.Height
.biWidth = Bmp.Width
.biCompression = BI_RGB
.biPlanes = 1
.biSize = 40
End With
Stride = ((Bmp.Width * 3 + 3) And &HFFFFFFFC)
ReDim Data(Stride * Bmp.Height - 1) As Byte
GetDIBits Me.hDC, Handle, 0, Bmp.Height, Data(0), BmpInfo, DIB_RGB_COLORS
DeleteObject Handle
Debug.Print Data(1), Data(2), Data(3), Data(4)
End Sub
你自己试下。
