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

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

 界面  执行程序下载地址:一键截图,点我下载。  获取最新版本和其他相关工具,可加入QQ群:920519255;

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

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

程序展开时,效果:

截图后,可编辑:

新增保留历史记录功能,选中历史记录,复制到剪切板。

截图类型:
静态:截取按下按钮那一刻的屏幕图片,图片是静止的(比如 截取视频,视频内容是静止的)。
动态:截屏内容是动态的,如果桌面有视频,是可以看到视频播放内容的。

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

开发思路

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

截取整个屏幕

       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, , , rc.Size, CopyPixelOperation.SourceCopy);
} return bitmap;
}

创建全屏窗体

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

图层布局

这个很有技巧!为了实现非截图区域阴影效果,费了一番心机!即使这样,感觉也比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 Height="*"></RowDefinition>
<RowDefinition Height="auto"></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 Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
<!--截图指示框-->
<Border x:Name="borderSelect"
HorizontalAlignment="Left" VerticalAlignment="Top"
BorderThickness="1" BorderBrush="Red"></Border>
<!--宽和高指示-->
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="auto"></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" Click="RadioArrow_Click" Foreground="Black" Padding="10,5,10,5" Style="{StaticResource stylePushButton}">↑</RadioButton>
<RadioButton x:Name="radioText" GroupName="editType" Click="RadioText_Click" Foreground="Black" Style="{StaticResource stylePushButton}">文</RadioButton>
<RadioButton x:Name="radioClose" Click="RadioClose_Click" Foreground="Red" Style="{StaticResource stylePushButton}">X</RadioButton>
</StackPanel>
</Grid> </StackPanel> </Grid>
</Grid>

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

 private void ImgScreen_MouseMove(object sender, MouseEventArgs e)
{
if (!_isMouseDown)
return; gridCover.Visibility = Visibility.Visible; //计算鼠标选中区域
Point currentPoint = e.GetPosition(imgScreen);
Point borderPoint = e.GetPosition(borderSelect); double xDelta = xDelta_BoderToImgScreen;
double yDelta = yDelta_BoderToImgScreen; _rectImgCut = ImageHelper.ToRect(currentPoint, _startPoint); Rect rectBoderCut = ImageHelper.ToRect(new Point(currentPoint.X + xDelta, currentPoint.Y + yDelta),
new Point(_startPoint.X + xDelta, _startPoint.Y + yDelta)); //设置方框位置和大小
Thickness thickness = new Thickness(rectBoderCut.Left, rectBoderCut.Top, , );
borderSelect.SetValue(FrameworkElement.MarginProperty, thickness);
imgCut.SetValue(FrameworkElement.MarginProperty, thickness); thickness = new Thickness(rectBoderCut.Left, , , );
txtCutInfo.SetValue(FrameworkElement.MarginProperty, thickness); borderSelect.Width = Math.Abs(_startPoint.X - currentPoint.X);
borderSelect.Height = Math.Abs(_startPoint.Y - currentPoint.Y);
borderSelect.Visibility = Visibility.Visible; //为了防止整个图 变暗,鼠标选中区域图像抠图,再在上层图像上显示
imgCut.Source = GetBitmapCut(); Int32Rect imgDestRect = GetCutRect();
txtCutInfo.Text = string.Format($"宽:{imgDestRect.Width} 高:{imgDestRect.Height}");
}

到此,程序主要逻辑处理完毕!麻雀虽小五脏俱全!这里用到不少wpf布局技巧。这些技巧与winform处理思虑差别还是很大的!wpf虽然苦涩难懂,感觉一入候门深似海!如果坚持下来,就会感到豁然开朗,也理解了微软的一片苦心!

程序运行效果与QQ截图很类似了。顺着这个思虑往前走,完全可以开发出与QQ截图一样的效果!

采用WPF开发截图程序,so easy!的更多相关文章

  1. 采用WPF技术开发截图程序

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

  2. OFD电子证照模版制作工具 --(采用wpf开发)

    前言  ofd应用的范围非常广,电子证照是其中非常重要的一个应用.同一类电子证照具有相同的板式.元数据:所以电子证照非常适合用模版来制作.模版就是板式样式固定,每个具体的证照只是文字或图片内容不同.比 ...

  3. 采用WPF开发第二版OFD阅读器,持续完善中,敬请期待!

    本人研究OFD多年,采用C#和QT开发了一系列ofd相关软件.在这些产品中,阅读器始终占据着非常重要的位置.可以说,阅读器是直接面向最终客户的产品.是集OFD各类知识之大成的产品.市面上的阅读器产品林 ...

  4. pdf文件内容查看器 -- 采用wpf开发

    前言 pdf是一种应用非常广的版式文档格式,已成为事实上的国际标准.关于pdf格式的文章汗牛充栋,本文也是关于pdf格式的文章,但是本文不是纸上谈兵:本人这几周一直研究pdf格式内容,不但对pfd格式 ...

  5. OFD电子文档阅读器功能说明(采用WPF开发,永久免费)

    特别说明 ofd阅读器开发语言为c#,具有完全自主产权,没有使用第三方ofd开发包.可以根据你的需求快速定制开发.本阅读器还在开发完善阶段,如有任何问题,可以联系我QQ:13712486.博客:htt ...

  6. 采用WPF技术,开发OFD电子文档阅读器

    前言 OFD是国家标准版式文档格式,于2016年生效.OFD文档国家标准参见<电子文件存储与交换格式版式文档>.既然是国家标准,OFD随后肯定会首先在政务系统使用,并逐步推向社会各个方面. ...

  7. WPF 开发自动开机启动程序

    原文:WPF 开发自动开机启动程序 本文告诉大家如何在 WPF 开发一个可以自动启动的程序 本文使用的自动开机启动方法是通过快捷方式放在启动文件夹的方式. 创建快捷方式 /// <summary ...

  8. SharePoint采用BCS开发第一个应用程序(两)

    SharePoint采用BCS开发第一个应用程序(两) 创建外部数据源 在本章中,我们使用AdventureWorksLT2008 SQL Server数据库作为外部数据源.下图显示了表SalesLT ...

  9. WPF开发的彩票程序(练手好例子) 附源码

    前言 WPF是.NET最新的界面开发库,开发界面非常灵活!但是学习WPF难度也非常大. 应朋友之邀,编写了一个小程序.程序虽小,五脏俱全,WPF开发的灵活性可窥见一斑. 对于新手学习有很好的借鉴意义, ...

随机推荐

  1. 大数据Hadoop基础入门到精通

    1.hadoop前世今生: 1) 搜索引擎:网络爬虫+索引服务器(生成索引+检索) 2) Doung Cutting 3)  Nutch a.分布式存储 b.分布式计算 4)GFS论文 doung c ...

  2. JSP学习笔记(5)——Servlet、监听器、过滤器、MVC模式介绍

    MVC模式 在讲解Servlet前,先介绍一下MVC模式. M:model 模型,相当于数据层,用于存放数据,如一个Java中的一个bean类 V:view 视图,相当于页面层,用于显示数据,如一个网 ...

  3. python根据搜索词下载百度图片

    # coding=utf-8 """根据搜索词下载百度图片""" import re import urllib import os def ...

  4. 3、循环链表(java实现)

    1.节点类 public class Node<T> { public T data; public Node next; } 2.实现类 public class CircularLin ...

  5. java8 把List<Object> 根据某字段去重

      import java.util.ArrayList;import java.util.List;import org.apache.shiro.SecurityUtils;import org. ...

  6. Angular4+Koa2+MongoDB开发个人博客

    **文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号.** ![file](https://img2018.cnblogs.com/blog/830272/201 ...

  7. Qt疑难问题-模态窗口父类被析构

    最近遇到一个朋友,问了我一个刁钻的问题,当你模态弹出一个窗体时,后台把这个窗体的父类给析构了,这个时候会出现什么样的情况? 听到问题后我真是一脸懵逼呀!从来没有这么写过代码. 随后写了一个简单的测试d ...

  8. Vue学习之不同组件之间的消息传递

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. AppScan工具使用-实战一

    本文首发于简书https://www.jianshu.com/p/639cf894838e 工具已经安装完成,废话不多说,直接拿手上的项目使用一下. 1.打开工具,点击文件-新建 2.打开新建扫描 3 ...

  10. Kerberoasting攻击

    前面我们介绍了<Windows本地认证>.<Windows网络认证>.<Windows域认证>和<SPN扫描>,这次继续讲解域内相关的东西. 0x01介 ...