C# WPF 使用 SnippingTool 效果抓取屏幕截图

发布于 2024-09-29 03:20:40 字数 1218 浏览 6 评论 0原文

我正在尝试在我的 WPF 应用程序中集成屏幕截图抓取功能,我希望它看起来像截图工具。

到目前为止,我已经通过创建不透明度设置为 0.5 和深色背景的全屏窗口(带有画布)来完成类似的任务。当我单击某处并开始拖动时,会绘制一个白色矩形,生成类似于 this 的效果。

我想要的是该矩形的内部部分,在背景画布上打开一个不透明的孔,以便我可以看到所选区域 - 就像剪切工具一样。

问题是,作为 .NET 的新手,我不知道如何或从哪里开始。对屏幕截图窗口的 OpacityMask 字段进行了一些研究和测试,但一无所获。

这是一个小视频来展示当前的效果。

编辑另外,作为奖励问题,是否有一种简单的方法可以抓取跨多个显示器(虚拟屏幕)的屏幕截图? Graphics.CopyFromScreen() 似乎仅适用于 1 个屏幕。
已经修复了这个问题,并且似乎适用于所有可能的奇怪的虚拟桌面布局:

// Capture screenie (rectangle is the area previously selected
double left = Canvas.GetLeft(this.rectangle);
double top = Canvas.GetTop(this.rectangle);

// Calculate left/top offset regarding to primary screen (where the app runs)
var virtualDisplay = System.Windows.Forms.SystemInformation.VirtualScreen;
var primaryScreen = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
if (virtualDisplay.Left < primaryScreen.Left)
{
    left -= Math.Abs(virtualDisplay.Left - primaryScreen.Left);
}
if (virtualDisplay.Top < primaryScreen.Top)
{
    top -= Math.Abs(virtualDisplay.Top - primaryScreen.Top);
}

I'm trying to integrate a screenshot grabbing feature in my WPF app and I'd like it to look like snipping tool.

So far I've managed accomplish something similar by creating a fullscreen window (with a canvas) with opacity set to 0.5 and dark background. When I click somewhere and start dragging, a white rectangle is drawn, generating an effect similar to this.

What I'd like to have is the inner part of that rectangle opening a opacity hole in the background canvas, so that I could see through the selected area - just like snipping tool.

Problem is, being fairly new to .NET, I have no idea how or where to start. Did some research and tests on the OpacityMask field of the screenshot window but got nowhere.

Here's a little vid to show the current effect.

Edit: Also, as bonus question, is there an easy way to grab a screenshot that spans across multiple monitors (virtual screen)? Graphics.CopyFromScreen() only seems to work for 1 screen.
Already fixed this and seems to work for all possible weird virtual desktop layouts:

// Capture screenie (rectangle is the area previously selected
double left = Canvas.GetLeft(this.rectangle);
double top = Canvas.GetTop(this.rectangle);

// Calculate left/top offset regarding to primary screen (where the app runs)
var virtualDisplay = System.Windows.Forms.SystemInformation.VirtualScreen;
var primaryScreen = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
if (virtualDisplay.Left < primaryScreen.Left)
{
    left -= Math.Abs(virtualDisplay.Left - primaryScreen.Left);
}
if (virtualDisplay.Top < primaryScreen.Top)
{
    top -= Math.Abs(virtualDisplay.Top - primaryScreen.Top);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝情姑娘 2024-10-06 03:20:40

您可以使用 CombinedGeometryGeometryCombineMode="Exclude" 创建“打孔”效果。样本:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" AllowsTransparency="True" 
    WindowStyle="None" Background="Transparent">
    <Canvas >
        <Path Stroke="Black" Fill="White" Opacity=".5">
            <Path.Data>
                <CombinedGeometry GeometryCombineMode="Exclude">
                    <CombinedGeometry.Geometry1>
                        <RectangleGeometry Rect="0,0,800,600" >
                        </RectangleGeometry>
                    </CombinedGeometry.Geometry1>
                    <CombinedGeometry.Geometry2>
                        <RectangleGeometry  Rect="50,50,100,100" >
                        </RectangleGeometry>
                    </CombinedGeometry.Geometry2>
                </CombinedGeometry>
            </Path.Data>
        </Path>
    </Canvas>
</Window>

You can have a CombinedGeometry with GeometryCombineMode="Exclude" creating a "punched" effect. Sample:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" AllowsTransparency="True" 
    WindowStyle="None" Background="Transparent">
    <Canvas >
        <Path Stroke="Black" Fill="White" Opacity=".5">
            <Path.Data>
                <CombinedGeometry GeometryCombineMode="Exclude">
                    <CombinedGeometry.Geometry1>
                        <RectangleGeometry Rect="0,0,800,600" >
                        </RectangleGeometry>
                    </CombinedGeometry.Geometry1>
                    <CombinedGeometry.Geometry2>
                        <RectangleGeometry  Rect="50,50,100,100" >
                        </RectangleGeometry>
                    </CombinedGeometry.Geometry2>
                </CombinedGeometry>
            </Path.Data>
        </Path>
    </Canvas>
</Window>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文