基于C# wpf实现桌面放大镜

 更新时间:2023年09月10日 08:57:38   作者:CodeOfCC  
做桌面截屏功能时需要放大镜,显示鼠标所在位置的放大图像,所以本文为大家介绍了如何基于C# wpf实现桌面放大镜功能,有需要的小伙伴可以参考下

前言

做桌面截屏功能时需要放大镜,显示鼠标所在位置的放大图像,在wpf中使用Bursh的ViewBox属性可以实现图像放大,桌面的画面则需要截屏了,总的来说还是比较容易实现的。

一、如何实现?

1、制作无边框窗口

推荐使用WindowChrome

<Window Background&#61;&#34;{x:Null}&#34; ResizeMode&#61;&#34;NoResize&#34;  WindowStyle&#61;&#34;None&#34;>

WindowChrome放在Window 标签内

<WindowChrome.WindowChrome>
        <WindowChrome GlassFrameThickness="-1"   CaptionHeight="0"   />
</WindowChrome.WindowChrome>

2、Viewbox放大

定义一个Ellipse 控件作为放大镜,Viewbox默认为相对单位,即范围时0-1,值越小放大越大

<Ellipse Stroke="LightBlue">
   <Ellipse.Fill>
       <ImageBrush x:Name="ib" Viewbox="0,0,0.5,0.5" />
   </Ellipse.Fill>
</Ellipse>

3、截屏显示

(1)、截屏

参考《C# wpf 使用GDI+实现截屏》里的简单截屏即完成。获取的数据类型为Bitmap。

(2)、转BitmapSource

参考《C# wpf Bitmap转换成WriteableBitmap(BitmapSource)的方法》将Bitmap转换为转换成wpf对象。

(3)、显示

获取到BitmapSource给控件赋值即可。

//显示到界面
ib.ImageSource = wb;

4、定时截屏

显示桌面必然需要实时的画面,所以需要定时截屏。

//启动定时器,截屏
var dispatcherTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(33), };
dispatcherTimer.Tick += (s, e) =>
{
   //截屏并显示
};
dispatcherTimer.Start();

二、完整代码

完整代码依赖System.Drawing,添加引用方法可以参考《C# wpf 使用GDI+实现截屏》。

MainWindow.xaml

<Window x:Class="WpfMagnifier.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfMagnifier"
        mc:Ignorable="d"
        Background="{x:Null}"
        ResizeMode="NoResize"
        WindowStyle="None"
        ShowInTaskbar="False"
        Topmost="True"
        Title="MainWindow" Height="200" Width="200" 
        MouseLeftButtonDown="Window_MouseDown">
    <WindowChrome.WindowChrome>
        <WindowChrome GlassFrameThickness="-1"   CaptionHeight="0"   />
    </WindowChrome.WindowChrome>
    <Ellipse Stroke="LightBlue">
        <Ellipse.Fill>
            <ImageBrush x:Name="ib" Viewbox="0,0,0.5,0.5" />
        </Ellipse.Fill>
    </Ellipse>
</Window>

MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace WpfMagnifier
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //启动定时器,截屏
            var dispatcherTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(33), };
            dispatcherTimer.Tick += (s, e) =>
            {
                //gdi+截屏,截取窗口左边的区域(可根据具体使用场景调整截屏位置),使用PointToScreen消除dpi影响
                var leftTop = PointToScreen(new Point(-Width, 0));
                var rightBottom = PointToScreen(new Point(0, Height));
                var bm = Snapshot((int)leftTop.X, (int)leftTop.Y, (int)(rightBottom.X - leftTop.X), (int)(rightBottom.Y - leftTop.Y));
                var wb = BitmapToWriteableBitmap(bm);
                //显示到界面
                ib.ImageSource = wb;
            };
            dispatcherTimer.Start();
        }
        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }
        /// <summary>
        /// 截取一帧图片
        /// </summary>
        /// <param name="x">x坐标</param>
        /// <param name="y">y坐标</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <returns>截屏后的位图对象,需要调用Dispose手动释放资源。</returns>
        public static System.Drawing.Bitmap Snapshot(int x, int y, int width, int height)
        {
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
            {
                graphics.CopyFromScreen(x, y, 0, 0, new System.Drawing.Size(width, height), System.Drawing.CopyPixelOperation.SourceCopy);
            }
            return bitmap;
        }
        //将Bitmap 转换成WriteableBitmap 
        public static WriteableBitmap BitmapToWriteableBitmap(System.Drawing.Bitmap src)
        {
            var wb = CreateCompatibleWriteableBitmap(src);
            System.Drawing.Imaging.PixelFormat format = src.PixelFormat;
            if (wb == null)
            {
                wb = new WriteableBitmap(src.Width, src.Height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);
                format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
            }
            BitmapCopyToWriteableBitmap(src, wb, new System.Drawing.Rectangle(0, 0, src.Width, src.Height), 0, 0, format);
            return wb;
        }
        //创建尺寸和格式与Bitmap兼容的WriteableBitmap
        public static WriteableBitmap CreateCompatibleWriteableBitmap(System.Drawing.Bitmap src)
        {
            System.Windows.Media.PixelFormat format;
            switch (src.PixelFormat)
            {
                case System.Drawing.Imaging.PixelFormat.Format16bppRgb555:
                    format = System.Windows.Media.PixelFormats.Bgr555;
                    break;
                case System.Drawing.Imaging.PixelFormat.Format16bppRgb565:
                    format = System.Windows.Media.PixelFormats.Bgr565;
                    break;
                case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
                    format = System.Windows.Media.PixelFormats.Bgr24;
                    break;
                case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
                    format = System.Windows.Media.PixelFormats.Bgr32;
                    break;
                case System.Drawing.Imaging.PixelFormat.Format32bppPArgb:
                    format = System.Windows.Media.PixelFormats.Pbgra32;
                    break;
                case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
                    format = System.Windows.Media.PixelFormats.Bgra32;
                    break;
                default:
                    return null;
            }
            return new WriteableBitmap(src.Width, src.Height, 0, 0, format, null);
        }
        //将Bitmap数据写入WriteableBitmap中
        public static void BitmapCopyToWriteableBitmap(System.Drawing.Bitmap src, WriteableBitmap dst, System.Drawing.Rectangle srcRect, int destinationX, int destinationY, System.Drawing.Imaging.PixelFormat srcPixelFormat)
        {
            var data = src.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), src.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, srcPixelFormat);
            dst.WritePixels(new Int32Rect(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height), data.Scan0, data.Height * data.Stride, data.Stride, destinationX, destinationY);
            src.UnlockBits(data);
        }
    }
}

三、效果预览

显示的是窗口(放大镜)左边的画面

到此这篇关于基于C# wpf实现桌面放大镜的文章就介绍到这了,更多相关C# wpf放大镜内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#实现上位机与欧姆龙PLC通讯(FINS)

    C#实现上位机与欧姆龙PLC通讯(FINS)

    这篇文章主要介绍了C#实现上位机与欧姆龙PLC通讯(FINS)方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • C#操作SQLite数据库方法小结(创建,连接,插入,查询,删除等)

    C#操作SQLite数据库方法小结(创建,连接,插入,查询,删除等)

    这篇文章主要介绍了C#操作SQLite数据库方法,包括针对SQLite数据库的创建,连接,插入,查询,删除等操作,并提供了一个SQLite的封装类,需要的朋友可以参考下
    2016-07-07
  • c#中查询表达式GroupBy的使用方法

    c#中查询表达式GroupBy的使用方法

    本篇文章介绍一下GroupBy的使用方法,包括实验基础数据用例,通过实例代码给大家介绍的非常详细,需要的朋友跟随小编一起看看吧
    2021-11-11
  • dotnet如何将文件删除到回收站

    dotnet如何将文件删除到回收站

    这篇文章主要给大家介绍了关于dotnet如何将文件删除到回收站的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用dotnet具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • C# 弹出窗口show()和showdialog()的两种方式

    C# 弹出窗口show()和showdialog()的两种方式

    本文主要介绍了C# 弹出窗口show()和showdialog()的两种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Unity Undo实现原理和使用方法详解

    Unity Undo实现原理和使用方法详解

    本文将详细介绍Unity Undo实现原理和使用方法,并提供多个使用例子,帮助开发者更好地理解和应用该功能,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • C#特性-迭代器(上)及一些研究过程中的副产品

    C#特性-迭代器(上)及一些研究过程中的副产品

    这篇文章主要介绍了C#特性-迭代器(上)及一些研究过程中的副产品,需要的朋友可以参考下
    2014-12-12
  • C#使用Socket实现通信的方法示例

    C#使用Socket实现通信的方法示例

    这篇文章主要介绍了C#使用Socket实现通信的方法示例,文章按照 Socket 的 创建、连接、传输数据、释放资源的过程来写,给出方法、参数的详细信息,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2024-06-06
  • C#子类对基类方法的继承、重写与隐藏详解

    C#子类对基类方法的继承、重写与隐藏详解

    这篇文章主要介绍了C#子类对基类方法的继承、重写与隐藏的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-07-07
  • C# Chart绘制简单图形波形

    C# Chart绘制简单图形波形

    这篇文章主要为大家详细介绍了C# Chart绘制简单图形波形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论