iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >WPF仿微信实现截图功能的方法详解
  • 336
分享到

WPF仿微信实现截图功能的方法详解

2024-04-02 19:04:59 336人浏览 八月长安
摘要

目录前言 一、ScreenCut.cs 代码如下二、ScreenCut.xaml 代码如下 三、ScreenCutExample.xaml 代码如下每日一笑 肚子

每日一笑

肚子疼,去厕所排便,结果什么都没拉出来。看着自己坐在马桶上痛苦又努力却一无所获的样子,仿佛看到了自己平凡的一生。 

前言 

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

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

一、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;
            else
                h = 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();

到此这篇关于WPF仿微信实现截图功能的方法详解的文章就介绍到这了,更多相关WPF截图内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: WPF仿微信实现截图功能的方法详解

本文链接: https://www.lsjlt.com/news/165552.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • WPF仿微信实现截图功能的方法详解
    目录前言 一、ScreenCut.cs 代码如下二、ScreenCut.xaml 代码如下 三、ScreenCutExample.xaml 代码如下每日一笑 肚子...
    99+
    2024-04-02
  • C#仿QQ实现简单的截图功能
    目录实现功能开发环境实现代码实现效果接上一篇写的截取电脑屏幕,我们在原来的基础上加一个选择区域的功能,实现自定义选择截图。 个人比较懒,上一篇的代码就不重新设计了,就简单改一下呈现方...
    99+
    2024-04-02
  • java仿QQ微信聊天室功能的实现
    话不多说,先上图                      &...
    99+
    2024-04-02
  • vue 实现网页截图功能详解
    最近项目有一个需求,需要上传图片,但是客户上传的图片大小不一,所以我们需要规定客户的图片比例,但又需要是客户所需的,所以就想到了截图 实现效果 我们的架构是vue,所以用的是一个v...
    99+
    2024-04-02
  • Android如何实现仿微信@好友功能
    这篇文章主要介绍Android如何实现仿微信@好友功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!先上个效果图就是这么个功能1. 分析需求输入@跳转到联系人界面,选中一个或者多个好友返回到当前界面按退格键删除整块内...
    99+
    2023-05-30
    android
  • 微信小程序图片压缩功能的实现方法
    微信小程序图片压缩功能的实现方法 :1、在 wx.chooseImage 接口选择相机图片。2、在 wx.getImageInfo 接口获取图片信息。3、计算压缩比例和最终图片的长宽。4、创建 canvas 绘制最终图片。5、在 wx.ca...
    99+
    2024-04-02
  • 微信小程序图片上传功能的实现方法
    目录前言首先是静态布局和样式部分下面是js的部分,我已详细备注~~~总结前言 最近做了个小程序,涉及到了图片上传的功能,今天给大家详细介绍下如何实现小程序图片上传,话不多说先上代码 ...
    99+
    2024-04-02
  • Flutter实现仿微信分享功能的示例代码
    目录1.首先去pub官网2 在微信开放平台注册开发者账号以及创建你的应用程序3 在分享页面3.1 初始化3.2 检测微信是否安装3.3 分享微信消息总结本文设计到的知识点有主要问题F...
    99+
    2024-04-02
  • android 仿微信demo——注册功能实现(移动端)
    目录移动端注册功能实现测试总结移动端注册功能实现 微信的注册界面每一个文本段都有下划线且默认颜色都是灰色,当其中一个文本段获取焦点会将下划线的颜色变为绿色,而且文本输入框的光标也是绿...
    99+
    2024-04-02
  • android 仿微信demo——注册功能实现(服务端)
    目录服务端注册功能实现创建项目创建web层和客户端完成数据交互创建service层处理业务逻辑功能创建dao层操作数据库通过JDBC工具类访问数据库mysql中创建数据库和表测试总结...
    99+
    2024-04-02
  • android 仿微信demo——登录功能实现(服务端)
    目录服务端登录功能实现测试总结 上一篇文章实现了微信登录的移动端功能,下面继续完善功能,实现微信登录服务端功能 服务端登录功能实现 在以往文章里已经实现了服务端mvc框架,而登录和...
    99+
    2024-04-02
  • Python实现超快窗口截图功能详解
    实现思路是先获取到当前最上面活动的窗口信息,然后提取该窗口的名称信息。 之后获取窗口的坐标信息,即左上角的开始坐标及右下角的结束坐标。最后直接截图并将截图的图片进行展示。 其中用到...
    99+
    2024-04-02
  • Android如何实现仿微信右滑返回功能
    这篇文章将为大家详细讲解有关Android如何实现仿微信右滑返回功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。先上效果图,如下:先分析一下功能的主要技术点,右滑即手势判断,当滑到一直距离时才执行返回,...
    99+
    2023-05-30
    android
  • android 仿微信demo——登录功能实现(移动端)
    目录移动端登录功能实现测试移动端登录功能实现 登录功能基本和注册一样,唯一不同的是登录可以实现两种登录方式(微信号和手机号),也就是布局不一样。所以需要两个布局,两个activity...
    99+
    2024-04-02
  • Vue拖动截图功能的简单实现方法
    拖动鼠标进行页面截图(也可指定区域拖动截图) 一、安装html2canvas、vue-cropper npm i html2canvas --save //用于...
    99+
    2024-04-02
  • WPF实现绘制统计图(柱状图)的方法详解
    目录前言实现代码效果预览前言 有小伙伴提出需要实现统计图。  由于在WPF中没有现成的统计图控件,所以我们自己实现一个。 PS:有更好的方式欢迎推荐。 实现代码 一、创建...
    99+
    2024-04-02
  • Java模仿微信如何实现零钱通简易功能
    本篇文章为大家展示了Java模仿微信如何实现零钱通简易功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1. 需求描述使用Java 开发零钱通项目, 模仿微信实现简易功能,可以完成收益入账,消费,查...
    99+
    2023-06-22
  • Android仿微信雷达扫描效果的实现方法
    本文主要给大家介绍的是关于Android实现微信雷达扫描效果的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:废话不多说 先上图(用AS录制的 转换工具不是很好 所以看得效果不是很好)效果图示例代码Activity 代码public...
    99+
    2023-05-31
    android 雷达扫描
  • Java编程调用微信支付功能的方法详解
    本文实例讲述了Java编程调用微信支付功能的方法。分享给大家供大家参考,具体如下:微信开发文档地址:https://mp.weixin.qq.com/wiki/home/从调用处开始我的流程: 1.点击“支付”按钮,去后台 —-> 2...
    99+
    2023-05-31
    java 支付
  • android 仿微信demo——微信通讯录界面功能实现(移动端,服务端)
    目录移动端微信通讯录界面功能实现服务端微信通讯录界面功能实现测试总结 前面我们实现了微信消息界面的实现,这篇继续完善微信功能,实现微信通讯录界面 移动端微信通讯录界面功能实现 微信...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作