基于C#?wpf實(shí)現(xiàn)桌面放大鏡
前言
做桌面截屏功能時(shí)需要放大鏡,顯示鼠標(biāo)所在位置的放大圖像,在wpf中使用Bursh的ViewBox屬性可以實(shí)現(xiàn)圖像放大,桌面的畫面則需要截屏了,總的來說還是比較容易實(shí)現(xiàn)的。
一、如何實(shí)現(xiàn)?
1、制作無邊框窗口
推薦使用WindowChrome
<Window Background="{x:Null}" ResizeMode="NoResize" WindowStyle="None">WindowChrome放在Window 標(biāo)簽內(nèi)
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="-1" CaptionHeight="0" />
</WindowChrome.WindowChrome>2、Viewbox放大
定義一個(gè)Ellipse 控件作為放大鏡,Viewbox默認(rèn)為相對(duì)單位,即范圍時(shí)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+實(shí)現(xiàn)截屏》里的簡(jiǎn)單截屏即完成。獲取的數(shù)據(jù)類型為Bitmap。
(2)、轉(zhuǎn)BitmapSource
參考《C# wpf Bitmap轉(zhuǎn)換成WriteableBitmap(BitmapSource)的方法》將Bitmap轉(zhuǎn)換為轉(zhuǎn)換成wpf對(duì)象。
(3)、顯示
獲取到BitmapSource給控件賦值即可。
//顯示到界面 ib.ImageSource = wb;
4、定時(shí)截屏
顯示桌面必然需要實(shí)時(shí)的畫面,所以需要定時(shí)截屏。
//啟動(dòng)定時(shí)器,截屏
var dispatcherTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(33), };
dispatcherTimer.Tick += (s, e) =>
{
//截屏并顯示
};
dispatcherTimer.Start();二、完整代碼
完整代碼依賴System.Drawing,添加引用方法可以參考《C# wpf 使用GDI+實(shí)現(xiàn)截屏》。
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();
//啟動(dòng)定時(shí)器,截屏
var dispatcherTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(33), };
dispatcherTimer.Tick += (s, e) =>
{
//gdi+截屏,截取窗口左邊的區(qū)域(可根據(jù)具體使用場(chǎng)景調(diào)整截屏位置),使用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坐標(biāo)</param>
/// <param name="y">y坐標(biāo)</param>
/// <param name="width">寬</param>
/// <param name="height">高</param>
/// <returns>截屏后的位圖對(duì)象,需要調(diào)用Dispose手動(dòng)釋放資源。</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 轉(zhuǎn)換成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;
}
//創(chuàng)建尺寸和格式與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數(shù)據(jù)寫入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);
}
}
}三、效果預(yù)覽
顯示的是窗口(放大鏡)左邊的畫面

到此這篇關(guān)于基于C# wpf實(shí)現(xiàn)桌面放大鏡的文章就介紹到這了,更多相關(guān)C# wpf放大鏡內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#基于WebBrowser獲取cookie的實(shí)現(xiàn)方法
這篇文章主要介紹了C#基于WebBrowser獲取cookie的實(shí)現(xiàn)方法,實(shí)例分析了C#基于WebBrowser簡(jiǎn)單讀取瀏覽谷歌網(wǎng)站cookie的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-11-11
C# Winform實(shí)現(xiàn)自定義分頁(yè)控件
一些第三方的分頁(yè)控件要么就是界面不夠美觀大方,要么就是使用起來感覺很麻煩,所以本文就為大家介紹一下如何利用Winform自定義分頁(yè)控件,需要的可以參考一下2023-07-07
C#異常處理的最佳實(shí)踐與內(nèi)存模型深度剖析
C#提供了強(qiáng)大的異常處理機(jī)制,它幫助開發(fā)者捕獲并響應(yīng)運(yùn)行時(shí)的錯(cuò)誤,然而,異常的處理不僅僅是捕獲錯(cuò)誤,它還需要合理的策略來確保代碼的性能、可維護(hù)性和可靠性,本文將深入探討C#異常處理的最佳實(shí)踐,如何有效記錄日志,避免性能損失,并對(duì)C#的內(nèi)存模型做詳細(xì)解析2025-01-01
C#使用Queue<T>進(jìn)行隊(duì)列設(shè)計(jì)
Queue<T>類提供了許多方法和屬性,用于處理隊(duì)列中的元素,本文主要介紹了C#使用Queue<T>進(jìn)行隊(duì)列設(shè)計(jì),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
C#獲取進(jìn)程的主窗口句柄的實(shí)現(xiàn)方法
C#獲取進(jìn)程的主窗口句柄的實(shí)現(xiàn)方法,需要的朋友可以參考一下2013-04-04
程序中兩個(gè)Double類型相加出現(xiàn)誤差的解決辦法
本篇文章介紹了,程序中兩個(gè)Double類型相加出現(xiàn)誤差的解決辦法。需要的朋友參考下2013-04-04

