Sha*_*hed 6 directx-11 sharpdx
我是DirectX的新手,并尝试使用SharpDX使用Desktop Duplication API捕获屏幕截图.
我想知道是否有任何简单的方法来创建我可以在CPU中使用的位图(即保存在文件等)
我使用以下代码获取桌面屏幕截图:
var factory = new SharpDX.DXGI.Factory1();
var adapter = factory.Adapters1[0];
var output = adapter.Outputs[0];
var device = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware,
DeviceCreationFlags.BgraSupport |
DeviceCreationFlags.Debug);
var dev1 = device.QueryInterface<SharpDX.DXGI.Device1>();
var output1 = output.QueryInterface<Output1>();
var duplication = output1.DuplicateOutput(dev1);
OutputDuplicateFrameInformation frameInfo;
SharpDX.DXGI.Resource desktopResource;
duplication.AcquireNextFrame(50, out frameInfo, out desktopResource);
var desktopSurface = desktopResource.QueryInterface<Surface>();
Run Code Online (Sandbox Code Playgroud)
任何人都可以给我一些关于如何从desktopSurface(DXGI.Surface实例)创建位图对象的想法?
小智 6
我刚刚完成了这个,虽然我不打算多说这段代码!
public byte[] GetScreenData()
{
// We want to copy the texture from the back buffer so
// we don't hog it.
Texture2DDescription desc = BackBuffer.Description;
desc.CpuAccessFlags = CpuAccessFlags.Read;
desc.Usage = ResourceUsage.Staging;
desc.OptionFlags = ResourceOptionFlags.None;
desc.BindFlags = BindFlags.None;
byte[] data = null;
using (var texture = new Texture2D(DeviceDirect3D, desc))
{
DeviceContextDirect3D.CopyResource(BackBuffer, texture);
using (Surface surface = texture.QueryInterface<Surface>())
{
DataStream dataStream;
var map = surface.Map(SharpDX.DXGI.MapFlags.Read, out dataStream);
int lines = (int)(dataStream.Length / map.Pitch);
data = new byte[surface.Description.Width * surface.Description.Height * 4];
int dataCounter = 0;
// width of the surface - 4 bytes per pixel.
int actualWidth = surface.Description.Width * 4;
for (int y = 0; y < lines; y++)
{
for (int x = 0; x < map.Pitch; x++)
{
if (x < actualWidth)
{
data[dataCounter++] = dataStream.Read<byte>();
}
else
{
dataStream.Read<byte>();
}
}
}
dataStream.Dispose();
surface.Unmap();
}
}
return data;
}
Run Code Online (Sandbox Code Playgroud)
这将获得一个byte [],然后可以用它来生成位图.
以下是我保存到png图像的方法.
using (var stream = await file.OpenAsync( Windows.Storage.FileAccessMode.ReadWrite ))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
double dpi = DisplayProperties.LogicalDpi;
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight,
(uint)width, (uint)height, dpi, dpi, pixelData);
encoder.BitmapTransform.ScaledWidth = (uint)newWidth;
encoder.BitmapTransform.ScaledHeight = (uint)newHeight;
await encoder.FlushAsync();
waiter.Set();
}
Run Code Online (Sandbox Code Playgroud)
我知道这已经回答了一段时间了,也许你现在已经知道了:3但是如果其他人被卡住了我希望这会有所帮助!
桌面复制 API 的 MSDN 页面告诉我们图像的格式:
DXGI 通过新的 IDXGIOutputDuplication::AcquireNextFrame 方法提供包含当前桌面图像的表面。无论当前显示模式是什么,桌面图像的格式始终为DXGI_FORMAT_B8G8R8A8_UNORM 。
您可以使用Surface.Map(MapFlags, out DataStream)get 方法访问 CPU 上的数据。
代码应如下所示*:
DataStream dataStream;
desktopSurface.Map(MapFlags.Read, out dataStream);
for(int y = 0; y < surface.Description.Width; y++) {
for(int x = 0; x < surface.Description.Height; x++) {
// read DXGI_FORMAT_B8G8R8A8_UNORM pixel:
byte b = dataStream.Read<byte>();
byte g = dataStream.Read<byte>();
byte r = dataStream.Read<byte>();
byte a = dataStream.Read<byte>();
// color (r, g, b, a) and pixel position (x, y) are available
// TODO: write to bitmap or process otherwise
}
}
desktopSurface.Unmap();
Run Code Online (Sandbox Code Playgroud)
*免责声明:我手头没有安装 Windows 8,我只是按照文档进行操作。我希望这有效:)
| 归档时间: |
|
| 查看次数: |
6607 次 |
| 最近记录: |