dxgi返回黑色位图,桌面区域捕获
当使用涡流捕获桌面时,它可以正常工作。虽然,当我尝试使用矩形的x或y位置以外的任何其他值时,它仅作为黑色位图返回框架。我用于参考的代码位于此处: https:// github。 com/diogotr7/desktopduplicationsamples/blob/master/vorticecore/program.cs ,但它遇到了相同的问题。我尝试更改var框架中的大多数值,而var mapdest却没有很多运气。
public void Start()
{
_isCapturing = true;
DXGI.CreateDXGIFactory1<IDXGIFactory1>(out var factory);
if (factory == null)
{
return;
}
var adapter = factory.GetAdapter(0);
var output = adapter.GetOutput(0);
var output1 = output.QueryInterface<IDXGIOutput1>();
//D3D12.D3D12CreateDevice(adapter, FeatureLevel.Level_12_0, out ID3D12Device? device);
D3D11.D3D11CreateDevice(adapter, DriverType.Unknown, DeviceCreationFlags.None, _featureLevels, out var device);
if (device == null)
throw new Exception("Unable to Locate Device.");
// Width/Height of desktop to capture
Rectangle rectangle = new Rectangle(0, 0,
output.Description.DesktopCoordinates.Right,
output.Description.DesktopCoordinates.Bottom);
// Create Staging texture CPU-accessible
var texture2dDescription = new Texture2DDescription
{
ArraySize = 1,
BindFlags = BindFlags.None,
CPUAccessFlags = CpuAccessFlags.Read | CpuAccessFlags.Write,
Format = Format.B8G8R8A8_UNorm,
Height = rectangle.Bottom,
MipLevels = 1,
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Staging,
Width = rectangle.Right
};
Task.Factory.StartNew(() =>
{
// Duplicate the output
using var duplicatedOutput = output1.DuplicateOutput(device);
while (_isCapturing)
{
try
{
var currentFrame = device.CreateTexture2D(texture2dDescription);
Thread.Sleep(50);
rectangle.X = 0;
duplicatedOutput.AcquireNextFrame(100, out var frameInfo, out var desktopResource);
if (desktopResource == null)
continue;
var tempTexture = desktopResource.QueryInterface<ID3D11Texture2D>();
device.ImmediateContext.CopyResource(currentFrame, tempTexture);
var dataBox = device.ImmediateContext.Map(currentFrame, 0);
var frame = new Bitmap(rectangle.Right, rectangle.Bottom, PixelFormat.Format32bppRgb);
var mapDest = frame.LockBits(rectangle, ImageLockMode.WriteOnly, frame.PixelFormat);
for (int y = rectangle.Y, sizeInBytesToCopy = rectangle.Width * 4; y < rectangle.Height; y++)
{
MemoryHelpers.CopyMemory(mapDest.Scan0 + y * rectangle.Right * 4,
dataBox.DataPointer + y * dataBox.RowPitch, sizeInBytesToCopy);
}
frame.UnlockBits(mapDest);
ScreenRefreshed?.Invoke(this, frame);
desktopResource.Dispose();
frame.Dispose();
tempTexture.Dispose();
currentFrame.Dispose();
}
catch (Exception e)
{
if (e.HResult != Vortice.DXGI.ResultCode.WaitTimeout.Code)
{
Trace.TraceError(e.Message);
Trace.TraceError(e.StackTrace);
}
}
duplicatedOutput.ReleaseFrame();
}
});
}
When capturing the desktop using Vortice with the code below it works just fine. Although, when I try to use any other value than 0 for the X or Y location of the rectangle it only returns frame as a black bitmap. The code I used for reference is located here: https://github.com/diogotr7/DesktopDuplicationSamples/blob/master/VorticeCore/Program.cs, but it suffers from the same problem. I have tried altering most values in the var frame and var mapDest with not much luck.
public void Start()
{
_isCapturing = true;
DXGI.CreateDXGIFactory1<IDXGIFactory1>(out var factory);
if (factory == null)
{
return;
}
var adapter = factory.GetAdapter(0);
var output = adapter.GetOutput(0);
var output1 = output.QueryInterface<IDXGIOutput1>();
//D3D12.D3D12CreateDevice(adapter, FeatureLevel.Level_12_0, out ID3D12Device? device);
D3D11.D3D11CreateDevice(adapter, DriverType.Unknown, DeviceCreationFlags.None, _featureLevels, out var device);
if (device == null)
throw new Exception("Unable to Locate Device.");
// Width/Height of desktop to capture
Rectangle rectangle = new Rectangle(0, 0,
output.Description.DesktopCoordinates.Right,
output.Description.DesktopCoordinates.Bottom);
// Create Staging texture CPU-accessible
var texture2dDescription = new Texture2DDescription
{
ArraySize = 1,
BindFlags = BindFlags.None,
CPUAccessFlags = CpuAccessFlags.Read | CpuAccessFlags.Write,
Format = Format.B8G8R8A8_UNorm,
Height = rectangle.Bottom,
MipLevels = 1,
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Staging,
Width = rectangle.Right
};
Task.Factory.StartNew(() =>
{
// Duplicate the output
using var duplicatedOutput = output1.DuplicateOutput(device);
while (_isCapturing)
{
try
{
var currentFrame = device.CreateTexture2D(texture2dDescription);
Thread.Sleep(50);
rectangle.X = 0;
duplicatedOutput.AcquireNextFrame(100, out var frameInfo, out var desktopResource);
if (desktopResource == null)
continue;
var tempTexture = desktopResource.QueryInterface<ID3D11Texture2D>();
device.ImmediateContext.CopyResource(currentFrame, tempTexture);
var dataBox = device.ImmediateContext.Map(currentFrame, 0);
var frame = new Bitmap(rectangle.Right, rectangle.Bottom, PixelFormat.Format32bppRgb);
var mapDest = frame.LockBits(rectangle, ImageLockMode.WriteOnly, frame.PixelFormat);
for (int y = rectangle.Y, sizeInBytesToCopy = rectangle.Width * 4; y < rectangle.Height; y++)
{
MemoryHelpers.CopyMemory(mapDest.Scan0 + y * rectangle.Right * 4,
dataBox.DataPointer + y * dataBox.RowPitch, sizeInBytesToCopy);
}
frame.UnlockBits(mapDest);
ScreenRefreshed?.Invoke(this, frame);
desktopResource.Dispose();
frame.Dispose();
tempTexture.Dispose();
currentFrame.Dispose();
}
catch (Exception e)
{
if (e.HResult != Vortice.DXGI.ResultCode.WaitTimeout.Code)
{
Trace.TraceError(e.Message);
Trace.TraceError(e.StackTrace);
}
}
duplicatedOutput.ReleaseFrame();
}
});
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码存在问题。以下是说明为什么它不超过一次的问题,需要一个奇怪的
睡眠
呼叫:但是,还有其他问题
frameinfo
参数具有有关所有这些的有用信息。这是一个似乎可以使用的版本(获取10帧并将其保存为位图文件):
There are issues with your code. Here are the issue that explain why it doesn't work more than once and requires a strange
Sleep
call:But there are other issues
frameInfo
parameter has useful information about all this.Here is a version that seems to work (acquires 10 frames and saves them as bitmap files):