I develop a .NET WinForms application and need to scale a lot of big images and display them as small icons on the form. I have problem with performance especially on specific machines. Thus my goal now is to use SharpDX to scale these image using Direct2D. Somehow images are scaled now, but I cannot copy image from DirectX bitmap to .NET one.
Private Sub CopyBitmapFromDxToGDI(bitmap As d2.Bitmap1, bmp As Drawing.Bitmap)
Dim d2dBitmapProps2 = New d2.BitmapProperties1(d2PixelFormat, 96, 96, BitmapOptions.CpuRead Or BitmapOptions.CannotDraw )
Dim d2dRenderTarget2 = New d2.Bitmap1(d2dContext, New Size2(bmp.Width, bmp.Height), d2dBitmapProps2)
d2dRenderTarget2.CopyFromRenderTarget(d2dContext)
Dim surface = d2dRenderTarget2.Surface
Dim dataStream As DataStream = Nothing
surface.Map(dxgi.MapFlags.Read, dataStream)
Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(
New System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
Dim offset = 3
Debug.WriteLine($"({surface.Description.Width}, {surface.Description.Height})")
For y As Integer = 0 To surface.Description.Height - 1
For x As Integer = 0 To surface.Description.Width -1
Dim b As Byte = dataStream.Read(Of Byte)()
Dim g As Byte = dataStream.Read(Of Byte)()
Dim r As Byte = dataStream.Read(Of Byte)()
Dim a As Byte = dataStream.Read(Of Byte)()
Marshal.WriteByte(bmpData.Scan0, offset, a)
offset += 1
Marshal.WriteByte(bmpData.Scan0, offset, r)
offset += 1
Marshal.WriteByte(bmpData.Scan0, offset, g)
offset += 1
Marshal.WriteByte(bmpData.Scan0, offset, b)
offset += 1
Next
Next
bmp.UnlockBits(bmpData)
surface.Unmap()
End Sub
The code is rather simple. I create a new bitmap that allows CPU access, get DataStream from it and then write this data to .NET bitmap byte by byte. However, this code mostly does not work. It can render image properly only if the target image have specific size. With specific size it simply crash with AccessViolationException. With specific size it is rendered strange:
Do you have an idea what I have missed in my code?