-
Notifications
You must be signed in to change notification settings - Fork 193
Open
Description
Edition Windows 10 Pro
Version 22H2
Installed on 11/23/2023
OS build 19045.4046
Experience Windows Feature Experience Pack 1000.19053.1000.0
Issue:
Run ScreenCaptureforHWND, select a folder window with normal size.
Maximize the window.
The frame returned by WGC contain some transparent pixels lines.
In my app, the background is black, so there will have black lines in the picture.
Evidence:
In my app
code to save frame in Sample App:
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//*********************************************************
#include "pch.h"
#include "SimpleCapture.h"
using namespace winrt;
using namespace Windows;
using namespace Windows::Foundation;
using namespace Windows::System;
//using namespace Windows::Graphics;
using namespace Windows::Graphics::Capture;
using namespace Windows::Graphics::DirectX;
using namespace Windows::Graphics::DirectX::Direct3D11;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Composition;
#include "C:\dev\Study\DXD\DirectXTex\DirectXTex\DirectXTex.h"
bool SaveTextureToImageFile(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, const wchar_t* filename)
{
ComPtr< ID3D11Resource > resource;
texture->QueryInterface(__uuidof(ID3D11Resource), reinterpret_cast<void**>(&resource));
DirectX::ScratchImage scratchImage;
HRESULT hr = DirectX::CaptureTexture(device, context, resource.get(), scratchImage);
if (SUCCEEDED(hr))
{
hr = DirectX::SaveToWICFile(scratchImage.GetImages(), scratchImage.GetImageCount(), DirectX::WIC_FLAGS_NONE, DirectX::GetWICCodec(DirectX::WIC_CODEC_PNG), filename);
if (SUCCEEDED(hr))
{
return true;
}
}
return false;
}
SimpleCapture::SimpleCapture(
IDirect3DDevice const& device,
GraphicsCaptureItem const& item)
{
m_item = item;
m_device = device;
// Set up
auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
d3dDevice->GetImmediateContext(m_d3dContext.put());
auto size = m_item.Size();
m_swapChain = CreateDXGISwapChain(
d3dDevice,
static_cast<uint32_t>(size.Width),
static_cast<uint32_t>(size.Height),
static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized),
2);
// Create framepool, define pixel format (DXGI_FORMAT_B8G8R8A8_UNORM), and frame size.
m_framePool = Direct3D11CaptureFramePool::Create(
m_device,
DirectXPixelFormat::B8G8R8A8UIntNormalized,
2,
size);
m_session = m_framePool.CreateCaptureSession(m_item);
m_lastSize = size;
m_frameArrived = m_framePool.FrameArrived(auto_revoke, { this, &SimpleCapture::OnFrameArrived });
}
// Start sending capture frames
void SimpleCapture::StartCapture()
{
CheckClosed();
m_session.StartCapture();
}
ICompositionSurface SimpleCapture::CreateSurface(
Compositor const& compositor)
{
CheckClosed();
return CreateCompositionSurfaceForSwapChain(compositor, m_swapChain.get());
}
// Process captured frames
void SimpleCapture::Close()
{
auto expected = false;
if (m_closed.compare_exchange_strong(expected, true))
{
m_frameArrived.revoke();
m_framePool.Close();
m_session.Close();
m_swapChain = nullptr;
m_framePool = nullptr;
m_session = nullptr;
m_item = nullptr;
}
}
void SimpleCapture::OnFrameArrived(
Direct3D11CaptureFramePool const& sender,
winrt::Windows::Foundation::IInspectable const&)
{
auto newSize = false;
{
auto frame = sender.TryGetNextFrame();
auto frameContentSize = frame.ContentSize();
if (frameContentSize.Width != m_lastSize.Width ||
frameContentSize.Height != m_lastSize.Height)
{
// The thing we have been capturing has changed size.
// We need to resize our swap chain first, then blit the pixels.
// After we do that, retire the frame and then recreate our frame pool.
newSize = true;
m_lastSize = frameContentSize;
m_swapChain->ResizeBuffers(
2,
static_cast<uint32_t>(m_lastSize.Width),
static_cast<uint32_t>(m_lastSize.Height),
static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized),
0);
}
{
auto frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
static int fileext = 0;
std::wstring filename = L"capturer" + std::to_wstring(fileext++) + L".png";
fileext % 100 == 0 ? SaveTextureToImageFile(GetDXGIInterfaceFromObject<ID3D11Device>(m_device).get(), m_d3dContext.get(), frameSurface.get(), filename.c_str()): 0;
com_ptr<ID3D11Texture2D> backBuffer;
check_hresult(m_swapChain->GetBuffer(0, guid_of<ID3D11Texture2D>(), backBuffer.put_void()));
m_d3dContext->CopyResource(backBuffer.get(), frameSurface.get());
}
}
DXGI_PRESENT_PARAMETERS presentParameters = { 0 };
m_swapChain->Present1(1, 0, &presentParameters);
if (newSize)
{
m_framePool.Recreate(
m_device,
DirectXPixelFormat::B8G8R8A8UIntNormalized,
2,
m_lastSize);
}
}
Metadata
Metadata
Assignees
Labels
No labels



