WPF实现截屏(仿微信)

 WPF开发者QQ群: 340500857  | 微信群 -> 进入公众号主页 加入组织

欢迎转发、分享、点赞、在看,谢谢~。0cdabee0d251d8e0f7ef85d0447f6d4c.png  

前言

      有小伙伴需要在软件反馈窗体增加截图功能需求,所以今天来实现一个仿微信的截图。

01

效果预览

效果预览(更多效果请下载源码体验):

02


代码如下

一、ScreenCut.cs 代码如下

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;namespace WPFDevelopers.Controls
{[TemplatePart(Name = CanvasTemplateName, Type = typeof(Canvas))][TemplatePart(Name = RectangleLeftTemplateName, Type = typeof(Rectangle))][TemplatePart(Name = RectangleTopTemplateName, Type = typeof(Rectangle))][TemplatePart(Name = RectangleRightTemplateName, Type = typeof(Rectangle))][TemplatePart(Name = RectangleBottomTemplateName, Type = typeof(Rectangle))][TemplatePart(Name = BorderTemplateName, Type = typeof(Border))][TemplatePart(Name = WrapPanelTemplateName, Type = typeof(WrapPanel))][TemplatePart(Name = ButtonSaveTemplateName, Type = typeof(Button))][TemplatePart(Name = ButtonCancelTemplateName, Type = typeof(Button))][TemplatePart(Name = ButtonCompleteTemplateName, Type = typeof(Button))]public class ScreenCut : Window{private const string CanvasTemplateName = "PART_Canvas";private const string RectangleLeftTemplateName = "PART_RectangleLeft";private const string RectangleTopTemplateName = "PART_RectangleTop";private const string RectangleRightTemplateName = "PART_RectangleRight";private const string RectangleBottomTemplateName = "PART_RectangleBottom";private const string BorderTemplateName = "PART_Border";private const string WrapPanelTemplateName = "PART_WrapPanel";private const string ButtonSaveTemplateName = "PART_ButtonSave";private const string ButtonCancelTemplateName = "PART_ButtonCancel";private const string ButtonCompleteTemplateName = "PART_ButtonComplete";private Canvas _canvas;private Rectangle _rectangleLeft, _rectangleTop, _rectangleRight, _rectangleBottom;private Border _border;private WrapPanel _wrapPanel;private Button _buttonSave,_buttonCancel, _buttonComplete;private Rect rect;private Point pointStart, pointEnd;private bool isMouseUp = false;static ScreenCut(){DefaultStyleKeyProperty.OverrideMetadata(typeof(ScreenCut), new FrameworkPropertyMetadata(typeof(ScreenCut)));}public override void OnApplyTemplate(){base.OnApplyTemplate();_canvas = GetTemplateChild(CanvasTemplateName) as Canvas;_rectangleLeft = GetTemplateChild(RectangleLeftTemplateName) as Rectangle;_rectangleTop = GetTemplateChild(RectangleTopTemplateName) as Rectangle;_rectangleRight = GetTemplateChild(RectangleRightTemplateName) as Rectangle;_rectangleBottom = GetTemplateChild(RectangleBottomTemplateName) as Rectangle;_border = GetTemplateChild(BorderTemplateName) as Border;_wrapPanel = GetTemplateChild(WrapPanelTemplateName) as WrapPanel;_buttonSave = GetTemplateChild(ButtonSaveTemplateName) as Button;if (_buttonSave != null)_buttonSave.Click += _buttonSave_Click;_buttonCancel = GetTemplateChild(ButtonCancelTemplateName) as Button;if (_buttonCancel != null)_buttonCancel.Click += _buttonCancel_Click;_buttonComplete = GetTemplateChild(ButtonCompleteTemplateName) as Button;if (_buttonComplete != null)_buttonComplete.Click += _buttonComplete_Click;this._canvas.Background = new ImageBrush(ChangeBitmapToImageSource(CaptureScreen()));_rectangleLeft.Width = _canvas.Width;_rectangleLeft.Height = _canvas.Height;}private void _buttonSave_Click(object sender, RoutedEventArgs e){SaveFileDialog dlg = new SaveFileDialog();dlg.FileName = $"WPFDevelopers{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg";dlg.DefaultExt = ".jpg";dlg.Filter = "image file|*.jpg";if (dlg.ShowDialog() == true){BitmapEncoder pngEncoder = new PngBitmapEncoder();pngEncoder.Frames.Add(BitmapFrame.Create(CutBitmap()));using (var fs = System.IO.File.OpenWrite(dlg.FileName)){pngEncoder.Save(fs);fs.Dispose();fs.Close();}}Close();}private void _buttonComplete_Click(object sender, RoutedEventArgs e){Clipboard.SetImage(CutBitmap());Close();}CroppedBitmap CutBitmap(){var renderTargetBitmap = new RenderTargetBitmap((int)_canvas.Width,(int)_canvas.Height, 96d, 96d, System.Windows.Media.PixelFormats.Default);renderTargetBitmap.Render(_canvas);return  new CroppedBitmap(renderTargetBitmap, new Int32Rect((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height));}private void _buttonCancel_Click(object sender, RoutedEventArgs e){Close();}protected override void OnPreviewKeyDown(KeyEventArgs e){if (e.Key == Key.Escape)Close();}protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e){if (!isMouseUp){_wrapPanel.Visibility = Visibility.Hidden;pointStart = e.GetPosition(_canvas);pointEnd = pointStart;rect = new Rect(pointStart, pointEnd);}}protected override void OnPreviewMouseMove(MouseEventArgs e){if (e.LeftButton == MouseButtonState.Pressed && !isMouseUp){var current = e.GetPosition(_canvas);MoveAllRectangle(current);}}protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e){if (!isMouseUp){_wrapPanel.Visibility = Visibility.Visible;Canvas.SetLeft(this._wrapPanel, rect.X + rect.Width - this._wrapPanel.ActualWidth);Canvas.SetTop(this._wrapPanel, rect.Y + rect.Height + 4);isMouseUp = true;}}void MoveAllRectangle(Point current){pointEnd = current;rect = new Rect(pointStart, pointEnd);this._rectangleLeft.Width = rect.X;this._rectangleLeft.Height = _canvas.Height;Canvas.SetLeft(this._rectangleTop, this._rectangleLeft.Width);this._rectangleTop.Width = rect.Width;double h = 0.0;if (current.Y < pointStart.Y)h = current.Y;elseh = current.Y - rect.Height;this._rectangleTop.Height = h;Canvas.SetLeft(this._rectangleRight, this._rectangleLeft.Width + rect.Width);this._rectangleRight.Width = _canvas.Width - (rect.Width + this._rectangleLeft.Width);this._rectangleRight.Height = _canvas.Height;Canvas.SetLeft(this._rectangleBottom, this._rectangleLeft.Width);Canvas.SetTop(this._rectangleBottom, rect.Height + this._rectangleTop.Height);this._rectangleBottom.Width = rect.Width;this._rectangleBottom.Height = _canvas.Height - (rect.Height + this._rectangleTop.Height);this._border.Height = rect.Height;this._border.Width = rect.Width;Canvas.SetLeft(this._border, rect.X);Canvas.SetTop(this._border, rect.Y);}System.Drawing.Bitmap CaptureScreen(){var bmpCaptured = new System.Drawing.Bitmap((int)SystemParameters.PrimaryScreenWidth, (int)SystemParameters.PrimaryScreenHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpCaptured)){g.SmoothingMode = SmoothingMode.AntiAlias;g.CompositingQuality = CompositingQuality.HighQuality;g.InterpolationMode = InterpolationMode.HighQualityBicubic;g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;g.PixelOffsetMode = PixelOffsetMode.HighQuality;g.CopyFromScreen(0, 0, 0, 0, bmpCaptured.Size, System.Drawing.CopyPixelOperation.SourceCopy);}return bmpCaptured;}[System.Runtime.InteropServices.DllImport("gdi32.dll")]public static extern bool DeleteObject(IntPtr hObject);ImageSource ChangeBitmapToImageSource(System.Drawing.Bitmap bitmap){IntPtr hBitmap = bitmap.GetHbitmap();ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap,IntPtr.Zero,Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());if (!DeleteObject(hBitmap)){throw new System.ComponentModel.Win32Exception();}return wpfBitmap;}}
}


二、ScreenCut.xaml 代码如下 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:controls="clr-namespace:WPFDevelopers.Controls"><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="Basic/ControlBasic.xaml"/><ResourceDictionary Source="../Styles/Styles.Buttons.xaml"/></ResourceDictionary.MergedDictionaries><Style x:Key="RectangleStyle" TargetType="{x:Type Rectangle}"><Setter Property="Fill" Value="{StaticResource BlackSolidColorBrush}"/><Setter Property="Opacity" Value=".5"/>
</Style><Style TargetType="{x:Type controls:ScreenCut}" BasedOn="{StaticResource ControlBasicStyle}"><Setter Property="WindowState" Value="Maximized"/><Setter Property="WindowStyle" Value="None"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type controls:ScreenCut}"><Canvas x:Name="PART_Canvas"Width="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}}"Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}}"><Rectangle x:Name="PART_RectangleLeft" Style="{StaticResource RectangleStyle}"/><Rectangle x:Name="PART_RectangleTop" Style="{StaticResource RectangleStyle}"/><Rectangle x:Name="PART_RectangleRight" Style="{StaticResource RectangleStyle}"/><Rectangle x:Name="PART_RectangleBottom" Style="{StaticResource RectangleStyle}"/><Border x:Name="PART_Border" BorderBrush="{StaticResource SuccessPressedSolidColorBrush}" BorderThickness="1"/><WrapPanel x:Name="PART_WrapPanel" Visibility="Hidden" Panel.ZIndex="99"Height="38" Background="{StaticResource WhiteSolidColorBrush}"VerticalAlignment="Center"><Button x:Name="PART_ButtonSave" Style="{StaticResource PathButton}"ToolTip="保存" Margin="10,0,0,0"><Button.Content><Path Fill="{StaticResource InfoPressedSolidColorBrush}" Width="18" Height="18" Stretch="Fill" Data="{StaticResource PathSave}"/></Button.Content></Button><Button x:Name="PART_ButtonCancel" Style="{StaticResource PathButton}"ToolTip="取消"><Button.Content><Path Fill="{StaticResource DangerPressedSolidColorBrush}" Width="14" Height="14" Stretch="Fill" Data="{StaticResource PathCancel}"/></Button.Content></Button><Button x:Name="PART_ButtonComplete"  Style="{StaticResource PathButton}"ToolTip="完成" Margin="0,0,10,0"><Button.Content><Path Fill="{StaticResource SuccessPressedSolidColorBrush}"  Width="20" Height="15" Stretch="Fill" Data="{StaticResource PathComplete}"/></Button.Content></Button></WrapPanel></Canvas></ControlTemplate></Setter.Value></Setter>
</Style>
</ResourceDictionary>


三、ScreenCutExample.xaml 代码如下

var screenCut = new ScreenCut();screenCut.ShowDialog();

源码地址

github:https://github.com/yanjinhuagood/WPFDevelopers.git

gitee:https://gitee.com/yanjinhua/WPFDevelopers.git

WPF开发者QQ群: 340500857 

blogs: https://www.cnblogs.com/yanjinhua

Github:https://github.com/yanjinhuagood

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/yanjinhuagood

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297582.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我妈要把闺蜜介绍给我当女朋友......

1 反正手没闲着啊▼2 这...这女孩子不会是您跳广场舞认识的吧&#xff1f;▼3 这就是生活▼4 有画面感了▼5 这种运动会想想就觉得很好看▼6 电脑屏幕不亮手机玩起来不够舒服▼7 这种脱衣方式可真是太酷啦&#xff01;▼你点的每个赞&#xff0c;我都认真当成了喜欢

topic数量是指什么_一个网站的IP、UV和PV到底是什么

在百度统计后台会看到“IP统计”、“UV统计”、“PV统计”&#xff0c;那么、什么是IP&#xff0c;什么是UV&#xff0c;什么又是PV&#xff0c;三者之间有什么关系&#xff0c;IP重要&#xff0c;还是UV重要&#xff0c;还是PV重要。什么是IP&#xff1f;IP即&#xff1a;Inte…

发布一个博客园专用Windows Live Writer代码插件

一直用Windows Live Writer写博客&#xff0c;不过没找到能与博客园配合得很好的代码插件&#xff0c;每次写完文章发布到博客园总要手动修改代码。所以我自己写了一个博客园专用的Windows Live Writer代码插件&#xff08;我知道这世界上已经有N个代码插件&#xff0c;好吧&am…

js深拷贝和浅拷贝

一、数组的深浅拷贝 在使用JavaScript对数组进行操作的时候&#xff0c;我们经常需要将数组进行备份&#xff0c;事实证明如果只是简单的将它赋予其他变量&#xff0c;那么我们只要更改其中的任何一个&#xff0c;然后其他的也会跟着改变&#xff0c;这就导致了问题的发生。 va…

dbeaver 数据转化 mapping_Python机器学习实例:数据竞赛-足球运动员身价估计

前言1&#xff0c;背景介绍每个足球运动员在转会市场都有各自的价码。本次数据练习的目的是根据球员的各项信息和能力来预测该球员的市场价值。2&#xff0c;数据来源FIFA20183&#xff0c;数据文件说明数据文件分为三个&#xff1a;train.csv         训练集     文件…

对SQL server、Oracle、MySQL和PostgreSQL进行OLTP性能测试(Benchmark)

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#xff0c;首发于 【掘金】&#x1f4e2;作者格言&#xff1a;生活在于…

【完整版】当大师遇到了理工男,只能吐血了...

全世界有3.14 % 的人已经关注了爆炸吧知识1、青年问禅师&#xff1a;“大师&#xff0c;我很爱我的女朋友&#xff0c;她也有很多优点&#xff0c;但是总有几个缺点让我非常讨厌&#xff0c;有什么方法能让她改变&#xff1f;”禅师浅笑&#xff0c;答&#xff1a;“方法很简单…

[FW]软件开发中的11个系统思维定律

“我会更加努力地工作”——一匹名叫Boxer的马&#xff08;出自乔治奥威尔的《动物农庄》&#xff09; 彼得圣吉在其著作《第五项修炼》中提到的系统思维定律同样适用于软件开发。 1. 今日的问题源于昨日的解决方案&#xff08;Today’s problems come from yesterday’s sol…

5单个编译总会编译全部_VS2019 v16.5 MSVC编译器后端更新汇总

MSVC更新汇总在Visual Studio 2019 v16.5中&#xff0c;我们已经对C后端进行了持续的改进更新&#xff0c;包括新增了一些新特性和优化点&#xff0c;编译时间优化&#xff0c;以及更好的安全性。下面我们来汇总一下目前关于MSVC编译器后端更新的要点&#xff1a;> Intel JC…

计算机职称 计算机二级证,国家计算机二级证书含金量有多高

首先感谢你的邀请&#xff0c;我们都知道在大学生涯考证中&#xff0c;计算机二级#计算机二级#基本是在校大学生必备的证书。当然我说的必考证书是针对已经了解计算机证书的&#xff0c;当然可能还有一些人不了解&#xff0c;那学姐简单来说一下&#xff0c;什么是全国计算机二…

无法使用此安装程序来安装 .net framework_NuGet是什么?理解与使用(上)

如果你了解python&#xff0c;那么它类似pip。如果你了解nodejs&#xff0c;那么它类似npm。如果你了解ruby&#xff0c;那么它类似gem。对&#xff0c;它就是一个包&#xff08;package&#xff09;管理平台&#xff0c;确切的说是 .net平台的包管理工具&#xff0c;它提供了一…

NoSQL 是否可以用来做日志中心 ?

咨询区 ikrain&#xff1a;请问大家在分布式程序中用 nosql 来做日志中心的经验&#xff1f;我做了一些研究&#xff0c;发现用 Mongodb 做日志中心是一个非常好的选择&#xff0c;而且我发现 log4net 对它也是直接集成的&#xff0c;比如: log4mongo-net 。不知道大家可推荐这…

长能耐了?想造反了?你老婆没了.......

1 提出问题的人一律直接解决掉▼2 今年的心理阴影是金字塔和钢琴键带来的▼3 广州考如何催收房租&#xff1f;▼4 想起了大雄的衣柜......▼5 这简直一毛一样▼6 我今天非要跳上去不可&#xff01;突然想到我还有点急事&#xff0c;告辞……▼7 据说&#xff0c;有不少男…

php 无限查找下级业绩_PHP 面试踩过的坑

因为最近需要面试&#xff0c;所以特意整理了一下面试所经历的一些面试题。分享一下&#xff0c;希望对自己有用&#xff0c;也对其他人有用。尚未有答案的&#xff0c;后面会陆续更新&#xff0c;如果有补充答案的&#xff0c;也十分感激。1.get,post 的区别**显示有区别 **ge…

python获取历史双色球数据_你的梦想,我来买单!Python分析双色球中奖号码竟成功获取特等奖

关于双色球的话题估计大家都听的很多&#xff0c;毕竟成本很低&#xff0c;但是收获很高。毕竟当利润达到100&#xff05;时,就有人敢于铤而走险。当利润达到200&#xff05;时,他们就敢于冒上断头台的危险。 而当利润达到300%他们就会践踏人间的一切法律。更何况是n倍的利润刺…

分布式、微服务必须配个日志管理系统才优秀,Exceptionless走起~~~

前言在真实的项目中&#xff0c;不管是功能日志、错误日志还是异常日志&#xff0c;已经是项目的重要组成部分。在原始的单体架构&#xff0c;通常看日志的方式简单粗暴&#xff0c;直接登录到服务器&#xff0c;把日志文件拷贝下来进行分析&#xff1b;而如今分布式、微服务架…

《TCP/IP详解卷1:协议》第6章 ICMP:Internet控制报文协议-读书笔记

章节回顾&#xff1a; 《TCP/IP详解卷1&#xff1a;协议》第1章 概述-读书笔记 《TCP/IP详解卷1&#xff1a;协议》第2章 链路层-读书笔记 《TCP/IP详解卷1&#xff1a;协议》第3章 IP&#xff1a;网际协议&#xff08;1&#xff09;-读书笔记 《TCP/IP详解卷1&#xff1a;协议…

10以内的分解与组成怎么教_狗狗酷炫的飞盘游戏怎么玩?分解步骤教你快速学会...

现在的铲屎官都喜欢训练自己的狗狗&#xff0c;训练狗狗不仅可以增加狗狗与主人的感情&#xff0c;还能增强狗狗的协调性&#xff0c;开发狗狗的智力&#xff0c;可谓一举两得。其中飞盘是大家都比较爱的活动&#xff0c;经常看看狗狗以华丽的身姿一跃接起主人扔的飞盘&#xf…

计算机组成与系统 报告,计算机组成与系统结构实验报告2

计算机组成与系统结构实验报告,西北工业大学评语: 课中检查完成的题号及题数&#xff1a; 成绩:自评成绩:95课后完成的题号与题数&#xff1a;实验报告实验名称&#xff1a; 班级&#xff1a;1.4 CPU 与简单模型机设计实验 日期&#xff1a; 2015.11.16 杨添文10011303 学号&am…

c++ 异步下获取线程执行结果_前端异步编程的那些事

啊一、异步编程的运行机制我们学习Javascript语言的时候就知道它的执行环境是”单线程“的。所谓”单线程“&#xff0c;就是指一次只能处理一个任务。如果有多个任务&#xff0c;就必须排队&#xff0c;前面一个任务完成&#xff0c;再执行后面一个任务。常见的浏览器无响应(假…