选择屏幕区域的最简单方法
Posted
技术标签:
【中文标题】选择屏幕区域的最简单方法【英文标题】:Easiest way to select screen region 【发布时间】:2012-10-04 18:39:56 【问题描述】:我正在用 C# + WPF 编写一个简单的程序,记录/序列化用户鼠标和键盘活动,然后他可以播放它。
它的某些功能需要用户指定屏幕中小区域的坐标。在文本框中输入左上角和右下角的坐标不是很舒服,所以我想以类似的方式选择它,如 Windows Snipping Tool、ZScreen/ShareX 等。
类似的,也许是简化的
实现它的最简单方法是什么?
我用谷歌搜索了很多,但没有找到任何简单明了的东西。 http://cropper.codeplex.com/源代码看起来太复杂了,我不需要图像,只需要相对于屏幕的坐标。
【问题讨论】:
我在这里找到了解决方案:***.com/questions/12770432/… 【参考方案1】:你可以试试这个静态类CaptureScreen
和Capture method
static public class CaptureScreen
public static BitmapSource Capture(Rect area)
IntPtr screenDC = GetDC(IntPtr.Zero);
IntPtr memDC = CreateCompatibleDC(screenDC);
IntPtr hBitmap = CreateCompatibleBitmap(screenDC, (int)SystemParameters.VirtualScreenWidth, (int)SystemParameters.VirtualScreenHeight);
SelectObject(memDC, hBitmap); // Select bitmap from compatible bitmap to memDC
// TODO: BitBlt may fail horribly
BitBlt(memDC, 0, 0, (int)area.Width, (int)area.Height, screenDC, (int)area.X, (int)area.Y, TernaryRasterOperations.SRCCOPY);
BitmapSource bsource = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
DeleteObject(hBitmap);
ReleaseDC(IntPtr.Zero, screenDC);
ReleaseDC(IntPtr.Zero, memDC);
return bsource;
#region WINAPI DLL Imports
[DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll", SetLastError = true)]
private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
private static extern IntPtr CreateBitmap(int nWidth, int nHeight, uint cPlanes, uint cBitsPerPel, IntPtr lpvBits);
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
private enum TernaryRasterOperations : uint
/// <summary>dest = source</summary>
SRCCOPY = 0x00CC0020,
/// <summary>dest = source OR dest</summary>
SRCPAINT = 0x00EE0086,
/// <summary>dest = source AND dest</summary>
SRCAND = 0x008800C6,
/// <summary>dest = source XOR dest</summary>
SRCINVERT = 0x00660046,
/// <summary>dest = source AND (NOT dest)</summary>
SRCERASE = 0x00440328,
/// <summary>dest = (NOT source)</summary>
NOTSRCCOPY = 0x00330008,
/// <summary>dest = (NOT src) AND (NOT dest)</summary>
NOTSRCERASE = 0x001100A6,
/// <summary>dest = (source AND pattern)</summary>
MERGECOPY = 0x00C000CA,
/// <summary>dest = (NOT source) OR dest</summary>
MERGEPAINT = 0x00BB0226,
/// <summary>dest = pattern</summary>
PATCOPY = 0x00F00021,
/// <summary>dest = DPSnoo</summary>
PATPAINT = 0x00FB0A09,
/// <summary>dest = pattern XOR dest</summary>
PATINVERT = 0x005A0049,
/// <summary>dest = (NOT dest)</summary>
DSTINVERT = 0x00550009,
/// <summary>dest = BLACK</summary>
BLACKNESS = 0x00000042,
/// <summary>dest = WHITE</summary>
WHITENESS = 0x00FF0062
[DllImport("gdi32.dll")]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);
#endregion
【讨论】:
我知道如何截屏。但我不知道如何让用户使用 ZScreen/ShareX/Cropper/WinSnippingTool 或我上面的屏幕截图中的选择矩形来选择它。以上是关于选择屏幕区域的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章
使用 QOpenGLWidget 进行屏幕外渲染的最简单方法