VB.NET Draw независимое от устройства растровое изображение в картинке - PullRequest
1 голос
/ 04 апреля 2019

Я зашел в тупик с моей программой. У меня в памяти есть простой массив, состоящий из значений RGB растрового изображения DIB (нет BITMAPFILEHEADER). Этот массив генерируется в C ++, но я пытаюсь отобразить его в VB.NET. Я не хочу использовать GDI +, потому что мне нужна грубая скорость.

Это мой код (изображение в файле не имеет заголовка, ширина: 1920 и высота: 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, кажется, преуспели

1 Ответ

1 голос
/ 05 апреля 2019

Я нашел решение.Я думаю, что проблема возникает из-за того, что CreateCompatibleDC создает сетку один пиксель на один пиксель.Из-за этого ограничения я просто использовал StretchDIBits на HDC графического блока:

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)

Конечно, в примере используются фиксированные значения только для целей тестирования.Работает без нареканий.

...