更新OpenCvSharp4版本到4.10.0,PaddleOCR到2.7.0.3,尝试修复bitblt导致崩溃的问题 (#1381)

This commit is contained in:
Takaranoao
2025-04-01 14:47:13 +08:00
committed by GitHub
parent 98b46e8f1b
commit cbaf1f6c36
30 changed files with 225 additions and 150 deletions

View File

@@ -46,13 +46,28 @@ public class BitBltCapture : IGameCapture
Gdi32.SafeHBITMAP hBitmap = Gdi32.SafeHBITMAP.Null;
try
{
User32.GetClientRect(_hWnd, out var windowRect);
int x = 0, y = 0;
if (!User32.GetClientRect(_hWnd, out var windowRect))
{
Debug.Fail("Failed to get client rectangle");
return null;
}
var width = windowRect.right - windowRect.left;
var height = windowRect.bottom - windowRect.top;
hdcSrc = User32.GetDC(_hWnd == IntPtr.Zero ? User32.GetDesktopWindow() : _hWnd);
if (hdcSrc.IsInvalid)
{
Debug.WriteLine($"Failed to get DC for {_hWnd}");
return null;
}
hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
if (hdcSrc.IsInvalid)
{
Debug.Fail("Failed to create CompatibleDC");
return null;
}
var bmi = new Gdi32.BITMAPINFO
{
@@ -68,18 +83,32 @@ public class BitBltCapture : IGameCapture
}
};
nint bits = 0;
hBitmap = Gdi32.CreateDIBSection(hdcDest, bmi, Gdi32.DIBColorMode.DIB_RGB_COLORS, out bits, IntPtr.Zero, 0);
hBitmap = Gdi32.CreateDIBSection(hdcDest, bmi, Gdi32.DIBColorMode.DIB_RGB_COLORS, out var bits,
IntPtr.Zero,
0);
if (hBitmap.IsInvalid || bits == 0)
{
Debug.WriteLine($"Failed to create dIB section for {_hWnd}");
return null;
}
var oldBitmap = Gdi32.SelectObject(hdcDest, hBitmap);
if (oldBitmap.IsNull)
{
return null;
}
Gdi32.StretchBlt(hdcDest, 0, 0, width, height, hdcSrc, x, y, width, height, Gdi32.RasterOperationMode.SRCCOPY);
if (!Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.RasterOperationMode.SRCCOPY))
{
Debug.WriteLine($"BitBlt failed for {_hWnd}");
return null;
}
var mat = new Mat(height, width, MatType.CV_8UC4, bits);
using var mat = Mat.FromPixelData(height, width, MatType.CV_8UC4, bits);
Gdi32.SelectObject(hdcDest, oldBitmap);
if (!mat.Empty())
{
Mat bgrMat = new Mat();
var bgrMat = new Mat();
Cv2.CvtColor(mat, bgrMat, ColorConversionCodes.BGRA2BGR);
return bgrMat;
}
@@ -95,12 +124,12 @@ public class BitBltCapture : IGameCapture
}
finally
{
if (hBitmap != Gdi32.SafeHBITMAP.Null)
if (!hBitmap.IsNull)
{
Gdi32.DeleteObject(hBitmap);
}
if (hdcDest != Gdi32.SafeHDC.Null)
if (!hdcDest.IsNull)
{
Gdi32.DeleteDC(hdcDest);
}

View File

@@ -19,8 +19,8 @@
<PackageReference Include="Vanara.PInvoke.User32" Version="4.0.2" />
<PackageReference Include="Vanara.PInvoke.SHCore" Version="4.0.2" />
<PackageReference Include="Vanara.Windows.Extensions" Version="4.0.2" />
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.8.0.20230708" />
<PackageReference Include="OpenCvSharp4.Windows" Version="4.8.0.20230708" />
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
<PackageReference Include="OpenCvSharp4.Windows" Version="4.10.0.20241108" />
</ItemGroup>
</Project>

View File

@@ -40,7 +40,7 @@ public class GraphicsCapture : IGameCapture
// 用于获取帧数据的临时纹理和暂存资源
private Texture2D? _stagingTexture;
private long _lastFrameTime = 0;
@@ -81,12 +81,14 @@ public class GraphicsCapture : IGameCapture
_captureFramePool.FrameArrived += OnFrameArrived;
_captureSession = _captureFramePool.CreateCaptureSession(_captureItem);
if (ApiInformation.IsPropertyPresent("Windows.Graphics.Capture.GraphicsCaptureSession", "IsCursorCaptureEnabled"))
if (ApiInformation.IsPropertyPresent("Windows.Graphics.Capture.GraphicsCaptureSession",
"IsCursorCaptureEnabled"))
{
_captureSession.IsCursorCaptureEnabled = false;
}
if (ApiInformation.IsWriteablePropertyPresent("Windows.Graphics.Capture.GraphicsCaptureSession", "IsBorderRequired"))
if (ApiInformation.IsWriteablePropertyPresent("Windows.Graphics.Capture.GraphicsCaptureSession",
"IsBorderRequired"))
{
_captureSession.IsBorderRequired = false;
}
@@ -110,7 +112,8 @@ public class GraphicsCapture : IGameCapture
ResourceRegion region = new();
DwmApi.DwmGetWindowAttribute<RECT>(hWnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, out var windowRect);
DwmApi.DwmGetWindowAttribute<RECT>(hWnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS,
out var windowRect);
User32.GetClientRect(_hWnd, out var clientRect);
//POINT point = default; // 这个点和 DwmGetWindowAttribute 结果差1
//User32.ClientToScreen(hWnd, ref point);
@@ -174,13 +177,14 @@ public class GraphicsCapture : IGameCapture
{
return;
}
// 限制最高处理帧率为66fps
var now = Kernel32.GetTickCount();
if (now - _lastFrameTime < 15)
{
return;
}
_lastFrameTime = now;
var frameSize = _captureItem.Size;
@@ -227,7 +231,7 @@ public class GraphicsCapture : IGameCapture
try
{
// 创建一个新的Mat
var newFrame = new Mat(stagingTexture.Description.Height, stagingTexture.Description.Width,
var newFrame = Mat.FromPixelData(stagingTexture.Description.Height, stagingTexture.Description.Width,
_isHdrEnabled ? MatType.MakeType(7, 4) : MatType.CV_8UC4, dataBox.DataPointer);
// 如果是HDR进行HDR到SDR的转换

View File

@@ -90,7 +90,7 @@ public static class Texture2DExtensions
MapMode.Read,
SharpDX.Direct3D11.MapFlags.None);
var mat = new Mat(staging.Description.Height, staging.Description.Width, MatType.CV_8UC4, dataBox.DataPointer);
var mat = Mat.FromPixelData(staging.Description.Height, staging.Description.Width, MatType.CV_8UC4, dataBox.DataPointer);
return mat;
}
catch (Exception e)