【问题标题】:C# WPF grab screenshot with SnippingTool effect带有 SnippingTool 效果的 C# WPF 抓取屏幕截图
【发布时间】:2011-05-01 06:08:17
【问题描述】:

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

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

我想要的是那个矩形的内部在背景画布上打开一个不透明的洞,这样我就可以看到选定的区域——就像截图工具一样。

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

这是一个little vid 来显示当前的效果。

编辑另外,作为一个额外的问题,有没有一种简单的方法来抓取跨多个显示器(虚拟屏幕)的屏幕截图? 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);
}

【问题讨论】:

  • 我看到你采取了抓取桌面截图的方法。有道理,尽管我有点想避免它!另外,我意识到 CopyFromScreen 可以输入负坐标(例如,如果我的另一个屏幕在主屏幕的左侧),所以现在这只是一个数学问题 :)
  • 如果你仔细看,截图工具也在抓取桌面截图

标签: c# wpf screenshot opacitymask


【解决方案1】:

您可以使用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>

【讨论】:

  • 这很好用,但有一个小问题:当鼠标移动到“打孔”区域时,您会丢失 MouseMove 事件。我想我必须将此解决方案与 Hans Passant 指出的解决方案混合使用。不过效果不错!
  • 我玩过这个,如果与抓取屏幕截图并将其用作窗口背景的方法结合使用,它会产生所需的效果,所以我将这个标记为正确- 即使我想保持桌面上正在发生的事情的“实时”视图(即在选择之前没有截图)。
  • 嗯,对你有好处。与保持实时视图一样好,我认为没有用户会关心或注意到。其实我是在看截图的时候才发现截图工具是截图的,我一直都在用这个工具。
  • @biasedbit:我知道这确实是一个旧线程,但我正在玩这个并且找到了一种不会丢失 MouseMove 事件并且仍然具有“实时”视图的方法。将上面的 XAML 中的 Canvas 放在另一个 Canvas 内,使用 Background=WhiteOpacity=0.1。 10% 的不透明度几乎是透明的,但它仍会阻止鼠标点击穿过窗口。只需从外部画布而不是内部获取所需的 MouseMove 命令,因为无论如何它们都应该冒泡到父级。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多