VB.NET 在图片框中绘制设备独立位图
VB.NET Draw device independent bitmap in picturebox
我的程序走到了尽头。我在内存中有一个由 DIB 位图的 RGB 值组成的简单数组(无 BITMAPFILEHEADER
)。这个数组是用 C++ 生成的,但我尝试在 VB.NET 中显示它。我不想使用 GDI+,因为我需要原始速度。
这是我的代码(文件中的图像没有header、width:1920和height:100,24位,总大小6220804):
Dim bData As Byte()
Dim br As BinaryReader = New BinaryReader(File.OpenRead("img1.bmp"))
bData = br.ReadBytes(br.BaseStream.Length) 'no headers just raw data
Dim g As Graphics = Me.CreateGraphics() 'System.Drawing.Graphics.FromImage(bmp) 'or PictureBox1.CreateGraphics()
Dim hdc As IntPtr = g.GetHdc()
Dim bmi As New BITMAPINFO
bmi.bmiheader = New BITMAPINFOHEADER
'Now we fill up the bmi (Bitmap information variable) with all the necessary data
bmi.bmiheader.biSize = 40 'Size, in bytes, of the header (always 40)
bmi.bmiheader.biPlanes = 1 'Number of planes (always one)
bmi.bmiheader.biBitCount = 24 'Bits per pixel (always 24 for image processing)
bmi.bmiheader.biCompression = 0 'Compression: none or RLE (always zero)
bmi.bmiheader.biWidth = 1920
bmi.bmiheader.biHeight = 100
bmi.bmiheader.biSizeImage = 6220804
Dim memHDC As IntPtr = CreateCompatibleDC(hdc)
StretchDIBits(memHDC, 0, 0, 1920, 100, 0, 0, 1920, 100, bData, bmi, 0, 13369376) ' Copy RGB values on an intermediary HDC
BitBlt(hdc, 0, 0, 1920, 100, memHDC, 0, 0, 13369376) 'Print directly from the memHDC
这是我的结构:
<StructLayout(LayoutKind.Sequential)>
Structure RGBQUAD
Public rgbBlue As Byte
Public rgbGreen As Byte
Public rgbRed As Byte
Public rgbReserved As Byte
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Class BITMAPINFOHEADER
Public biSize As Int32
Public biWidth As Int32
Public biHeight As Int32
Public biPlanes As Int16
Public biBitCount As Int16
Public biCompression As Int32
Public biSizeImage As Int32
Public biXPelsPerMeter As Int32
Public biYPelsPerMeter As Int32
Public biClrUsed As Int32
Public biClrImportant As Int32
End Class
<StructLayout(LayoutKind.Sequential)>
Private Structure BITMAPINFO
Dim bmiheader As BITMAPINFOHEADER
Dim bmiColors As RGBQUAD
End Structure
我测试了几乎所有可能的变量、HDC 和图形组合。什么都不管用!我哪里失败了?
注意:StretchDIBits 和 BitBlt 似乎成功了
我找到了解决办法。我认为问题出在 CreateCompatibleDC 创建一个像素一个像素的网格这一事实。
由于这个限制,我只是在图片框的 HDC 上使用 StretchDIBits
:
Dim bData As Byte()
Dim br As BinaryReader = New BinaryReader(File.OpenRead("img1_arr.bmp"))
bData = br.ReadBytes(br.BaseStream.Length)
Dim g As Graphics = PictureBox1.CreateGraphics() 'or Me.CreateGraphics()
Dim dsthdc As IntPtr = g.GetHdc()
Dim bmi As New BITMAPINFO
bmi.bmiheader = New BITMAPINFOHEADER
'Now we fill up the bmi (Bitmap information variable) with all the necessary data
bmi.bmiheader.biSize = 40 'Size, in bytes, of the header (always 40)
bmi.bmiheader.biPlanes = 1 'Number of planes (always one)
bmi.bmiheader.biBitCount = 24 'Bits per pixel (always 24 for image processing)
bmi.bmiheader.biCompression = 0 'Compression: none or RLE (always zero)
bmi.bmiheader.biWidth = 1920
bmi.bmiheader.biHeight = 1080
bmi.bmiheader.biSizeImage = 6220804
StretchDIBits(dsthdc, 0, 0, 1920, 1080, 0, 0, 1920, 1080, bData, bmi, 0, SRCCOPY)
当然,该示例仅出于测试目的使用固定值。它运行完美。
我的程序走到了尽头。我在内存中有一个由 DIB 位图的 RGB 值组成的简单数组(无 BITMAPFILEHEADER
)。这个数组是用 C++ 生成的,但我尝试在 VB.NET 中显示它。我不想使用 GDI+,因为我需要原始速度。
这是我的代码(文件中的图像没有header、width:1920和height:100,24位,总大小6220804):
Dim bData As Byte()
Dim br As BinaryReader = New BinaryReader(File.OpenRead("img1.bmp"))
bData = br.ReadBytes(br.BaseStream.Length) 'no headers just raw data
Dim g As Graphics = Me.CreateGraphics() 'System.Drawing.Graphics.FromImage(bmp) 'or PictureBox1.CreateGraphics()
Dim hdc As IntPtr = g.GetHdc()
Dim bmi As New BITMAPINFO
bmi.bmiheader = New BITMAPINFOHEADER
'Now we fill up the bmi (Bitmap information variable) with all the necessary data
bmi.bmiheader.biSize = 40 'Size, in bytes, of the header (always 40)
bmi.bmiheader.biPlanes = 1 'Number of planes (always one)
bmi.bmiheader.biBitCount = 24 'Bits per pixel (always 24 for image processing)
bmi.bmiheader.biCompression = 0 'Compression: none or RLE (always zero)
bmi.bmiheader.biWidth = 1920
bmi.bmiheader.biHeight = 100
bmi.bmiheader.biSizeImage = 6220804
Dim memHDC As IntPtr = CreateCompatibleDC(hdc)
StretchDIBits(memHDC, 0, 0, 1920, 100, 0, 0, 1920, 100, bData, bmi, 0, 13369376) ' Copy RGB values on an intermediary HDC
BitBlt(hdc, 0, 0, 1920, 100, memHDC, 0, 0, 13369376) 'Print directly from the memHDC
这是我的结构:
<StructLayout(LayoutKind.Sequential)>
Structure RGBQUAD
Public rgbBlue As Byte
Public rgbGreen As Byte
Public rgbRed As Byte
Public rgbReserved As Byte
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Class BITMAPINFOHEADER
Public biSize As Int32
Public biWidth As Int32
Public biHeight As Int32
Public biPlanes As Int16
Public biBitCount As Int16
Public biCompression As Int32
Public biSizeImage As Int32
Public biXPelsPerMeter As Int32
Public biYPelsPerMeter As Int32
Public biClrUsed As Int32
Public biClrImportant As Int32
End Class
<StructLayout(LayoutKind.Sequential)>
Private Structure BITMAPINFO
Dim bmiheader As BITMAPINFOHEADER
Dim bmiColors As RGBQUAD
End Structure
我测试了几乎所有可能的变量、HDC 和图形组合。什么都不管用!我哪里失败了?
注意:StretchDIBits 和 BitBlt 似乎成功了
我找到了解决办法。我认为问题出在 CreateCompatibleDC 创建一个像素一个像素的网格这一事实。
由于这个限制,我只是在图片框的 HDC 上使用 StretchDIBits
:
Dim bData As Byte()
Dim br As BinaryReader = New BinaryReader(File.OpenRead("img1_arr.bmp"))
bData = br.ReadBytes(br.BaseStream.Length)
Dim g As Graphics = PictureBox1.CreateGraphics() 'or Me.CreateGraphics()
Dim dsthdc As IntPtr = g.GetHdc()
Dim bmi As New BITMAPINFO
bmi.bmiheader = New BITMAPINFOHEADER
'Now we fill up the bmi (Bitmap information variable) with all the necessary data
bmi.bmiheader.biSize = 40 'Size, in bytes, of the header (always 40)
bmi.bmiheader.biPlanes = 1 'Number of planes (always one)
bmi.bmiheader.biBitCount = 24 'Bits per pixel (always 24 for image processing)
bmi.bmiheader.biCompression = 0 'Compression: none or RLE (always zero)
bmi.bmiheader.biWidth = 1920
bmi.bmiheader.biHeight = 1080
bmi.bmiheader.biSizeImage = 6220804
StretchDIBits(dsthdc, 0, 0, 1920, 1080, 0, 0, 1920, 1080, bData, bmi, 0, SRCCOPY)
当然,该示例仅出于测试目的使用固定值。它运行完美。