【发布时间】:2020-05-27 14:09:24
【问题描述】:
我开发了一个 .NET WinForms 应用程序,需要缩放大量大图像并将它们显示为表单上的小图标。我有性能问题,尤其是在特定机器上。因此我现在的目标是使用 SharpDX 使用 Direct2D 来缩放这些图像。不知何故,图像现在被缩放了,但我无法将图像从 DirectX 位图复制到 .NET 中。
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
代码相当简单。我创建了一个允许 CPU 访问的新位图,从中获取 DataStream,然后将这些数据逐字节写入 .NET 位图。但是,此代码大多不起作用。只有当目标图像具有特定大小时,它才能正确渲染图像。对于特定大小,它只会因 AccessViolationException 而崩溃。对于特定大小,它会变得很奇怪:
您知道我在代码中遗漏了什么吗?
【问题讨论】:
-
很难看出问题出在哪里,因为没有所有代码。这可能是 GDI+ 位图和 ID2D1Bitmap1 格式之间的格式不匹配。此外,您必须使用从 surface.Map 返回的 Pitch(又名步幅)值。这是表面的确切宽度(以字节为单位),可能与图像的宽度不同。
-
offset的值好像有误。 SharpDX.DataStream Examples 的示例 #2 显示为每行计算的偏移量为offset = bitmapData.Stride * y。 -
谢谢@AndrewMorton。该示例有帮助,现在我计算每个像素在 DataStream 中的位置,这可以解决问题。 dataStream.Seek((y * dataRectangle.Pitch) + (x * 4), SeekOrigin.Begin) dataStream.Read(buffer, 0, 4)
标签: .net vb.net winforms sharpdx direct2d