Open utterances-bot opened 3 years ago
这几天在玩这块,碰上保存 Texture2D
到硬盘的问题,Google 搜了下刚好搜到吕大的 blog。
也看到了 SharpDX 的例子代码
整合了一下,用了吕大的思路,但是用了 SharpDX 里的 CopyMemory,这样应该会快一些。
public static void MapTexture2DToFile(SharpDX.Direct3D11.Texture2D texture, string filename)
{
var device = texture.Device;
var originDesc = texture.Description;
var desc = new Texture2DDescription
{
CpuAccessFlags = CpuAccessFlags.Read,
BindFlags = BindFlags.None,
Usage = ResourceUsage.Staging,
Width = originDesc.Width,
Height = originDesc.Height,
Format = originDesc.Format,
MipLevels = 1,
ArraySize = 1,
SampleDescription =
{
Count = 1,
Quality = 0
},
OptionFlags = ResourceOptionFlags.Shared
};
var texture2D = new Texture2D(device, desc);
device.ImmediateContext.CopyResource(texture, texture2D);
var mapSource = device.ImmediateContext.MapSubresource(texture2D, 0, MapMode.Read, MapFlags.None);
var bitmap = new System.Drawing.Bitmap(desc.Width, desc.Height);
var boundsRect = new System.Drawing.Rectangle(0, 0, desc.Width, desc.Height);
var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
var sourcePtr = mapSource.DataPointer;
var destPtr = mapDest.Scan0;
for (var y = 0; y < desc.Height; y++)
{
Utilities.CopyMemory(destPtr, sourcePtr, desc.Width * 4);
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
bitmap.UnlockBits(mapDest);
device.ImmediateContext.UnmapSubresource(texture, 0);
bitmap.Save(filename);
}
说起来,话说有没有办法将 Texture2D
转为 WPF 的 ImageSource,现在我是 Texture2D -> Gdi Bitmap -> MemoryStream -> WPF BitmapImage,不知道有没有更好的做法。
@h82258652 Texture2D -> byte[] -> MemoryStream -> WPF BitmapImage,这可以比你说的省两份内存空间(你的占 3 份,我的占 1 份)。
因为 Texture2D 到你没写的字节数组有一次拷贝,Gdi Bitmap 到 MemoryStream 有一次拷贝。 而我提到的 byte[] 到 Memory Stream 没有。
拷贝到bitmap可以使用lock+unlock得到backbuffer,然后直接memcpy就行吧
将 Direct3D11 在 GPU 中的纹理(Texture2D)导出到内存(Map)或导出成图片文件 - walterlv
将 Direct3D11 在 GPU 中的纹理(Texture2D)导出到内存(Map)或导出成图片文件
https://blog.walterlv.com/post/map-directx-surface-to-bitmap.html