采用WPF开发截图程序,so easy!

时间:2021-08-03 19:27:01

前言  QQ、微信截图功能已很强大了,似乎没必要在开发一个截图程序了。但是有时QQ热键就是被占用,不能快速的开启截屏;有时,天天挂着QQ,领导也不乐意。既然是程序员,就要自己开发截屏工具,功能随心所欲,岂不快哉。

再强调一点:工具就是生产力!没有掌握WPF之前,我是不会开发这么一个程序的,如果采用MFC、winform框架,工作量是相当的大,开发出来的效果肯定也比较low。本人用WPF,花了一天多的功夫,开发了这个小程序。程序的定位就功能简单,平时工作不碍事,用着的时候,一键截图!

 界面  执行程序下载地址: 一键截图,点我下载。

采用WPF开发截图程序,so easy!

为了不影响视觉, 程序主界面非常小。程序会在所有界面最前端展示。

有两个按钮1)“快捷截图”:截图后,立即将截图复制到剪切板。2)“截图+编辑”:截图后,可以在图上标注箭头和文字。

正在截图时,效果:

采用WPF开发截图程序,so easy!

截图后,可编辑:

采用WPF开发截图程序,so easy!

看似简单,对开发技巧要求很高。内行看门道!

开发思路

  常言道:看到的不一定是真实的。开发也要这样。程序叫截屏,你不要一股劲想着怎么截取别的窗口图案,肯定很费劲!思虑就是掩人耳目:先将整个屏幕复制,放到自己程序窗体中,窗体最大化,覆盖整个屏幕!用户看到还是整个屏幕,但是整个屏幕已被偷梁换柱!此后,你所有的操作都是在自己窗体上处理,当然可以随心所欲了!

截取整个屏幕

public Bitmap GetScreenSnapshot() { System.Drawing.Rectangle rc = SystemInformation.VirtualScreen; var bitmap = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (Graphics memoryGrahics = Graphics.FromImage(bitmap)) { memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy); } return bitmap; }

创建全屏窗体

采用WPF开发截图程序,so easy!

注意窗体属性,这样才能全面覆盖整个屏幕。

图层布局

这个很有技巧!为了实现非截图区域阴影效果,费了一番心机!即使这样,感觉也比winform用起来得心应手!

注:我不是一直贬低winform,但是要承认,这两个东西不是一个时代产物。wpf设计思路比winform先进很多。只是wpf新概念多,用的人少,开发起来常常蒙圈!经过一段迷茫期,前途就会光明了!

窗口的布局,不多说了!直接上代码。我对代码做了注释!

<Window.Resources> <ControlTemplate x:Key="templatePushButton" TargetType="RadioButton"> <Border x:Name="Part_Border" BorderThickness="1" BorderBrush="Gray" Background="{TemplateBinding Background}" Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}"> <ContentPresenter></ContentPresenter> </Border> <ControlTemplate.Triggers > <Trigger Property="IsChecked" Value="True"> <Setter TargetName="Part_Border" Property="BorderBrush" Value="Blue"></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="Part_Border" Property="Background" Value="#FFb2dff9"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <Style x:Key="stylePushButton" TargetType="RadioButton"> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="Padding" Value="8,5,8,5"></Setter> <Setter Property="Template" Value="{StaticResource templatePushButton}"></Setter> </Style> </Window.Resources> <Grid Background="Green" > <!-- 整个屏幕图像 --> <Image x:Name="imgScreen" MouseDown="ImgScreen_MouseDown" MouseUp="ImgScreen_MouseUp" Stretch="None" MouseMove="ImgScreen_MouseMove"> </Image> <!-- 覆盖一层黑色,半透明状 --> <Grid x:Name="gridCover" Visibility="Collapsed" Background="Black" Opacity="0.5"> </Grid> <Grid> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <!-- 前面覆盖了一层黑色,但是截取的图像不能覆盖,只能在这里再显示截取图像 --> <Grid x:Name="gridCutImg" MouseDown="ImgCut_MouseDown" MouseMove="ImgCut_MouseMove" MouseUp="ImgCut_MouseUp"> <Image x:Name="imgCut" Grid.RowSpan="3" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top"></Image> <!--用来画箭头和文字--> <Canvas x:Name="canvasEdit" HorizontalAlignment=‘Left‘ VerticalAlignment="Top" Background="Transparent"> </Canvas> </Grid> <!--显示提示信息--> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22" Foreground="Yellow" Opacity="0.8" >滑动鼠标开始截屏 截图保存到剪切板 按ESC键退出</TextBlock> <StackPanel Grid.RowSpan="3"> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> </Grid> <!--截图指示框--> <Border x:Name="borderSelect" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="1" BorderBrush="Red"></Border> <!--宽和高指示--> <Grid HorizontalAlignment="Stretch" > <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <TextBlock x:Name="txtCutInfo" Padding="8,5,8,5" HorizontalAlignment="Left" Background="White" VerticalAlignment="Center">1</TextBlock> <StackPanel x:Name="stackEdit" Orientation="Horizontal" HorizontalAlignment="Right" Grid.Column="1" Margin="2"> <RadioButton x:Name="radioArrow" GroupName="editType" Foreground="Black" Padding="10,5,10,5">↑</RadioButton> <RadioButton x:Name="radioText" GroupName="editType" Foreground="Black">文</RadioButton> <RadioButton x:Name="radioClose" Foreground="Red">X</RadioButton> </StackPanel> </Grid> </StackPanel> </Grid> </Grid>

当鼠标移动时,不断的计算选中区域,设置borderSelect属性。