C\#캡 처 서비스의 실현
주의:Win 32 패키지 참조C\#BitBlt 로 창 캡 처 하기
Github 예시 공사:SimpleWindowCapture
1.캡 처 인터페이스
using System;
using Win32Proxy;
namespace CaptureProxy
{
internal interface ICaptureHelper
{
bool Init(string windowName);
bool Init(IntPtr handle);
void Cleanup();
bool RefreshWindow();
bool ChangeWindowHandle(string windowName);
bool ChangeWindowHandle(IntPtr handle);
IntPtr Capture();
bool Capture(out IntPtr bitsPtr, out int bufferSize, out Win32Types.Rect rect);
Win32Types.Rect WindowRect { get; }
Win32Types.Rect ClientRect { get; }
int BitmapDataSize { get; }
IntPtr BitmapPtr { get; }
Win32Types.BitmapInfo BitmapInfo { get; }
}
}
using System.ComponentModel;
namespace CaptureProxy
{
public enum CaptureType
{
[Description(" CreateDIBSection , , D3D ")]
CreateDibSection = 0,
[Description(" PrintWindow , (16ms ), D3D ")]
PrintWindow
}
}
2.캡 처 추상 류
using System;
using Win32Proxy;
namespace CaptureProxy
{
internal abstract class AbsCaptureHelper : ICaptureHelper
{
public Win32Types.Rect WindowRect => _windowRect;
public Win32Types.Rect ClientRect => WinClientRect;
public int BitmapDataSize => _bmpDataSize;
public IntPtr BitmapPtr => HBitmap;
public Win32Types.BitmapInfo BitmapInfo { get; } = new Win32Types.BitmapInfo();
protected IntPtr HWnd = IntPtr.Zero;
protected IntPtr HScrDc = IntPtr.Zero;
protected IntPtr HMemDc = IntPtr.Zero;
protected IntPtr HBitmap = IntPtr.Zero;
protected IntPtr HOldBitmap = IntPtr.Zero;
private Win32Types.Rect _windowRect;
protected Win32Types.Rect WinClientRect;
private int _bmpDataSize;
protected abstract bool CommonInit();
protected abstract IntPtr DoCapture();
protected abstract bool DoCapture(out IntPtr bitsPtr);
public bool Init(string windowName)
{
var handle = Win32Funcs.FindWindowWrapper(null, windowName);
if (handle.Equals(IntPtr.Zero))
{
return false;
}
return Init(handle);
}
public bool Init(IntPtr handle)
{
HWnd = handle;
//
if (!Win32Funcs.GetWindowRectWrapper(HWnd, out _windowRect)
|| !Win32Funcs.GetClientRectWrapper(HWnd, out WinClientRect))
{
return false;
}
_bmpDataSize = WinClientRect.Width * WinClientRect.Height * 3;
return CommonInit();
}
public void Cleanup()
{
if (HBitmap.Equals(IntPtr.Zero))
{
return;
}
//
Win32Funcs.SelectObjectWrapper(HMemDc, HOldBitmap);
Win32Funcs.DeleteObjectWrapper(HBitmap);
Win32Funcs.DeleteDcWrapper(HMemDc);
Win32Funcs.ReleaseDcWrapper(HWnd, HScrDc);
HWnd = IntPtr.Zero;
HScrDc = IntPtr.Zero;
HMemDc = IntPtr.Zero;
HBitmap = IntPtr.Zero;
HOldBitmap = IntPtr.Zero;
//_bitsPtr = IntPtr.Zero;
}
public bool RefreshWindow()
{
return ChangeWindowHandle(HWnd);
}
public bool ChangeWindowHandle(string windowName)
{
Cleanup();
return Init(windowName);
}
public bool ChangeWindowHandle(IntPtr handle)
{
Cleanup();
return Init(handle);
}
public IntPtr Capture()
{
if (HBitmap.Equals(IntPtr.Zero) || HMemDc.Equals(IntPtr.Zero) || HScrDc.Equals(IntPtr.Zero))
{
return IntPtr.Zero;
}
return DoCapture();
}
public bool Capture(out IntPtr bitsPtr, out int bufferSize, out Win32Types.Rect rect)
{
bitsPtr = IntPtr.Zero;
bufferSize = _bmpDataSize;
rect = WinClientRect;
if (HBitmap.Equals(IntPtr.Zero) || HMemDc.Equals(IntPtr.Zero) || HScrDc.Equals(IntPtr.Zero))
{
return false;
}
return DoCapture(out bitsPtr);
}
}
}
3.캡 처 클래스 구현
using System;
using Win32Proxy;
namespace CaptureProxy
{
internal class DibCaptureHelper : AbsCaptureHelper
{
private Win32Types.BitmapInfo _bitmapInfo;
private IntPtr _bitsPtr = IntPtr.Zero;
protected override bool CommonInit()
{
//
_bitmapInfo = new Win32Types.BitmapInfo {bmiHeader = new Win32Types.BitmapInfoHeader()};
_bitmapInfo.bmiHeader.Init();
_bitmapInfo.bmiHeader.biWidth = WinClientRect.Width;
_bitmapInfo.bmiHeader.biHeight = WinClientRect.Height;
_bitmapInfo.bmiHeader.biPlanes = 1;
_bitmapInfo.bmiHeader.biBitCount = 24;
_bitmapInfo.bmiHeader.biSizeImage = (uint) (WinClientRect.Width * WinClientRect.Height);
_bitmapInfo.bmiHeader.biCompression = (uint) Win32Consts.BitmapCompressionMode.BI_RGB;
HScrDc = Win32Funcs.GetWindowDcWrapper(HWnd);
HMemDc = Win32Funcs.CreateCompatibleDcWrapper(HScrDc);
HBitmap = Win32Funcs.CreateDibSectionWrapper(HMemDc, ref _bitmapInfo,
(uint) Win32Consts.DibColorMode.DIB_RGB_COLORS,
out _bitsPtr, IntPtr.Zero, 0);
HOldBitmap = Win32Funcs.SelectObjectWrapper(HMemDc, HBitmap);
return true;
}
protected override IntPtr DoCapture()
{
var ret = Win32Funcs.BitBltWrapper(
HMemDc, 0, 0, WinClientRect.Width, WinClientRect.Height,
HScrDc, 0, 0,
(uint) Win32Consts.RasterOperationMode.SRCCOPY);
return ret ? _bitsPtr : IntPtr.Zero;
}
protected override bool DoCapture(out IntPtr bitsPtr)
{
bitsPtr = _bitsPtr;
var ret = Win32Funcs.BitBltWrapper(
HMemDc, 0, 0, WinClientRect.Width, WinClientRect.Height,
HScrDc, 0, 0,
(uint) Win32Consts.RasterOperationMode.SRCCOPY);
return ret;
}
}
}
using System;
using Win32Proxy;
namespace CaptureProxy
{
internal class PrintCaptureHelper : AbsCaptureHelper
{
protected override bool CommonInit()
{
HScrDc = Win32Funcs.GetWindowDcWrapper(HWnd);
HBitmap = Win32Funcs.CreateCompatibleBitmapWrapper(HScrDc, WinClientRect.Width, WinClientRect.Height);
HMemDc = Win32Funcs.CreateCompatibleDcWrapper(HScrDc);
HOldBitmap = Win32Funcs.SelectObjectWrapper(HMemDc, HBitmap);
return true;
}
protected override IntPtr DoCapture()
{
var ret = Win32Funcs.PrintWindowWrapper(HWnd, HMemDc,
(uint) Win32Consts.PrintWindowMode.PW_CLIENTONLY |
(uint) Win32Consts.PrintWindowMode.PW_RENDERFULLCONTENT);
return ret ? HBitmap : IntPtr.Zero;
}
protected override bool DoCapture(out IntPtr bitsPtr)
{
bitsPtr = HBitmap;
var ret = Win32Funcs.PrintWindowWrapper(HWnd, HMemDc,
(uint) Win32Consts.PrintWindowMode.PW_CLIENTONLY |
(uint) Win32Consts.PrintWindowMode.PW_RENDERFULLCONTENT);
return ret;
}
}
}
4.캡 처 서비스
using System;
using System.Collections.Generic;
using Win32Proxy;
namespace CaptureProxy
{
public class CaptureService
{
private readonly Dictionary<string, ICaptureHelper> _dicCaptureHelper;
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="windowName"> </param>
/// <param name="type"> </param>
/// <returns>true ,false </returns>
public bool RegisterCapture(string name, string windowName, CaptureType type = CaptureType.CreateDibSection)
{
if (string.IsNullOrEmpty(name) || _dicCaptureHelper.ContainsKey(name))
{
return false;
}
ICaptureHelper helper;
switch (type)
{
case CaptureType.CreateDibSection:
helper = new DibCaptureHelper();
break;
case CaptureType.PrintWindow:
helper = new PrintCaptureHelper();
break;
default:
return false;
}
if (!helper.Init(windowName))
{
return false;
}
_dicCaptureHelper.Add(name, helper);
return true;
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="handle"> </param>
/// <param name="type"> </param>
/// <returns>true ,false </returns>
public bool RegisterCapture(string name, IntPtr handle, CaptureType type = CaptureType.CreateDibSection)
{
if (string.IsNullOrEmpty(name) || _dicCaptureHelper.ContainsKey(name))
{
return false;
}
ICaptureHelper helper;
switch (type)
{
case CaptureType.CreateDibSection:
helper = new DibCaptureHelper();
break;
case CaptureType.PrintWindow:
helper = new PrintCaptureHelper();
break;
default:
return false;
}
if (!helper.Init(handle))
{
return false;
}
_dicCaptureHelper.Add(name, helper);
return true;
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <returns>true ,false </returns>
public bool IsRegister(string name)
{
return !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name);
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
public void UnRegisterCapture(string name)
{
if (string.IsNullOrEmpty(name) || !_dicCaptureHelper.ContainsKey(name))
{
return;
}
_dicCaptureHelper[name]?.Cleanup();
_dicCaptureHelper.Remove(name);
}
/// <summary>
///
/// </summary>
public void Cleanup()
{
foreach (var helper in _dicCaptureHelper)
{
helper.Value?.Cleanup();
}
_dicCaptureHelper.Clear();
}
public bool RefreshWindow(string name)
{
var ret = !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name);
if (ret)
{
ret = _dicCaptureHelper[name].RefreshWindow();
}
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="handle"> </param>
public bool ChangeWindowHandle(string name, IntPtr handle)
{
return !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name) &&
_dicCaptureHelper[name].ChangeWindowHandle(handle);
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="windowName"> </param>
public bool ChangeWindowHandle(string name, string windowName)
{
return !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name) &&
_dicCaptureHelper[name].ChangeWindowHandle(windowName);
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="winRect"> </param>
/// <returns>true ,false </returns>
public bool GetWindowRect(string name, out Win32Types.Rect winRect)
{
var ret = !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name);
winRect = ret ? _dicCaptureHelper[name].WindowRect : new Win32Types.Rect();
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="clientRect"> </param>
/// <returns>true ,false </returns>
public bool GetClientRect(string name, out Win32Types.Rect clientRect)
{
var ret = !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name);
clientRect = ret ? _dicCaptureHelper[name].ClientRect : new Win32Types.Rect();
return ret;
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="bmpDataSize"> </param>
/// <returns>true ,false </returns>
public bool GetBitmapDataSize(string name, out int bmpDataSize)
{
var ret = !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name);
bmpDataSize = ret ? _dicCaptureHelper[name].BitmapDataSize : 0;
return ret;
}
public IntPtr GetBitmapPtr(string name)
{
if (string.IsNullOrEmpty(name) || !_dicCaptureHelper.ContainsKey(name))
{
return IntPtr.Zero;
}
return _dicCaptureHelper[name].BitmapPtr;
}
public Win32Types.BitmapInfo GetBitmapInfo(string name)
{
if (string.IsNullOrEmpty(name) || !_dicCaptureHelper.ContainsKey(name))
{
return new Win32Types.BitmapInfo();
}
return _dicCaptureHelper[name].BitmapInfo;
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="bitsPtr"> </param>
/// <returns>true ,false </returns>
public bool Capture(string name, out IntPtr bitsPtr)
{
var ret = !string.IsNullOrEmpty(name) && _dicCaptureHelper.ContainsKey(name);
bitsPtr = ret ? _dicCaptureHelper[name].Capture() : IntPtr.Zero;
return ret && !bitsPtr.Equals(IntPtr.Zero);
}
/// <summary>
///
/// </summary>
/// <param name="name"> </param>
/// <param name="bitsPtr"> </param>
/// <param name="bufferSize"> </param>
/// <param name="texSize"> </param>
/// <returns>true ,false </returns>
public bool Capture(string name, out IntPtr bitsPtr, out int bufferSize, out Win32Types.Rect texSize)
{
if (string.IsNullOrEmpty(name) || !_dicCaptureHelper.ContainsKey(name))
{
bitsPtr = IntPtr.Zero;
bufferSize = 0;
texSize = new Win32Types.Rect();
return false;
}
return _dicCaptureHelper[name].Capture(out bitsPtr, out bufferSize, out texSize);
}
#region
private static CaptureService _instance;
private static readonly object LockHelper = new object();
private CaptureService()
{
_dicCaptureHelper = new Dictionary<string, ICaptureHelper>();
}
public static CaptureService Instance
{
get
{
if (_instance != null)
{
return _instance;
}
lock (LockHelper)
{
_instance = _instance ?? new CaptureService();
}
return _instance;
}
}
#endregion
}
}
5.예시 사용
using System;
using System.Threading;
using CaptureProxy;
using Win32Proxy;
namespace SimpleWindowCapture
{
internal sealed class CaptureHelper
{
public event Action<string, IntPtr, Win32Types.BitmapInfo> CaptureDone =
(captureName, bitmapPtr, bitmapInfo) => { };
public int Fps { get; set; } = 15;
private double TimerInterval => 1000.0 / Fps;
private string _captureName;
private Timer _timer;
public bool Start(string captureName, IntPtr handle, CaptureType type = CaptureType.CreateDibSection)
{
if (!CaptureService.Instance.RegisterCapture(captureName, handle, type))
{
return false;
}
_captureName = captureName;
// ,
_timer = new Timer(CaptureFunc, null,
TimeSpan.FromMilliseconds(0), Timeout.InfiniteTimeSpan);
return true;
}
public void Stop()
{
//
_timer?.Dispose();
_timer = null;
CaptureService.Instance.UnRegisterCapture(_captureName);
_captureName = string.Empty;
}
private void CaptureFunc(object state)
{
Capture();
//
_timer?.Change(TimeSpan.FromMilliseconds(TimerInterval), Timeout.InfiniteTimeSpan);
}
private void Capture()
{
IntPtr bitsPtr;
if (!CaptureService.Instance.Capture(_captureName, out bitsPtr))
{
return;
}
var bitmapPtr = CaptureService.Instance.GetBitmapPtr(_captureName);
var bitmapInfo = CaptureService.Instance.GetBitmapInfo(_captureName);
CaptureDone.Invoke(_captureName, bitmapPtr, bitmapInfo);
}
}
}
이상 은 C\#캡 처 서비스의 실현 에 대한 상세 한 내용 입 니 다.c\#캡 처 서비스 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.