C# WPF 截屏功能
原理: 在屏幕的分别使用左、上、下和右四个矩形填满屏幕,在鼠标按下拖动的时候,获取鼠标拖动形成的矩形区域。松开鼠标后,将矩形区域内的屏幕保存为图片
ScreenCutWnd.xaml
<Window x:Class="Goldou_Comment_WPF.Comment.ScreenCutWnd" 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:Goldou_Comment_WPF.Comment" mc:Ignorable="d" Title="ScreenCutWnd" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent" > <Canvas x:Name="DrawingBoard" MouseLeftButtonDown="DrawingBoard_MouseLeftButtonDown" MouseLeftButtonUp="DrawingBoard_MouseLeftButtonUp" MouseMove="DrawingBoard_MouseMove" > <Rectangle x:Name="rectangleLeft" Fill="Black" Opacity="0.3"></Rectangle> <Rectangle x:Name="rectangleTop" Fill="Black" Opacity="0.3"></Rectangle> <Rectangle x:Name="rectangleRight" Fill="Black" Opacity="0.3"></Rectangle> <Rectangle x:Name="rectangleBottom" Fill="Black" Opacity="0.3"></Rectangle> <Border x:Name="ScreenBorder" BorderBrush="LightGreen" Visibility="Hidden" BorderThickness="0.25" ></Border> <WrapPanel x:Name="WrapPanelBtn" Visibility="Hidden"> <Button x:Name="SaveBtn" Style="{StaticResource ButtonSuccess}" Margin="0,0,10,0" Content="保存" Click="Btn_Click"></Button> <Button x:Name="CancelBtn" Style="{StaticResource ButtonDanger}" Content="取消" Click="Btn_Click"></Button> </WrapPanel> </Canvas> </Window>
ScreenCutWnd.xaml.cs
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.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace Goldou_Comment_WPF.Comment { /// <summary> /// ScreenCutWnd.xaml 的交互逻辑 /// </summary> public partial class ScreenCutWnd : Window { private Rect rect; private Point pointStart, pointEnd; private bool isMouseUp = false; private bool IsFullScreen = false; //是否是截的全屏 public ScreenCutWnd() { InitializeComponent(); try { this.Left = 0; this.Top = 0; this.Width = SystemParameters.PrimaryScreenWidth; this.Height = SystemParameters.PrimaryScreenHeight; this.DrawingBoard.Width = SystemParameters.PrimaryScreenWidth; this.DrawingBoard.Height = SystemParameters.PrimaryScreenHeight; this.DrawingBoard.Background = new ImageBrush(tools.ChangeBitmapToImageSource(CaptureScreen())); rectangleLeft.Height = this.Height; rectangleLeft.Width = this.Width; } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } } private void DrawingBoard_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { try { if (!isMouseUp) { if (ScreenBorder.Visibility == Visibility.Visible) { ScreenBorder.Visibility = Visibility.Hidden; } pointStart = e.GetPosition(DrawingBoard); pointEnd = pointStart; rect = new Rect(pointStart, pointEnd); } } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } e.Handled = true; } private void DrawingBoard_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { try { if (rect.Width + 2 >= this.Width&& rect.Height + 2 >= this.Height) { IsFullScreen = true; } else { IsFullScreen = false; } if (!isMouseUp && rect.Width > 0 && rect.Height > 0) { WrapPanelBtn.Visibility = Visibility.Visible; if (rect.Width+2>= this.Width) { Canvas.SetLeft(this.WrapPanelBtn, rect.Width - this.WrapPanelBtn.ActualWidth); } if (rect.Height+2>= this.Height) { Canvas.SetTop(this.WrapPanelBtn, rect.Height - this.WrapPanelBtn.ActualHeight); } else { Canvas.SetLeft(this.WrapPanelBtn, rect.X + rect.Width - this.WrapPanelBtn.ActualWidth); Canvas.SetTop(this.WrapPanelBtn, rect.Y + rect.Height + 4); } isMouseUp = true; } } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } e.Handled = true; } private void DrawingBoard_MouseMove(object sender, MouseEventArgs e) { try { if (e.LeftButton == MouseButtonState.Pressed && !isMouseUp) { if (ScreenBorder.Visibility != Visibility.Visible) { ScreenBorder.Visibility = Visibility.Visible; } Point current = e.GetPosition(DrawingBoard); MoveAllRectangle(current); } } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } e.Handled = true; } protected override void OnKeyDown(KeyEventArgs e) { try { if (e.Key == Key.Escape) { this.Close(); } } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } } private void MoveAllRectangle(Point current) { try { pointEnd = current; rect = new Rect(pointStart, pointEnd); this.rectangleLeft.Width = rect.X; this.rectangleLeft.Height = DrawingBoard.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 = DrawingBoard.Width - (rect.Width + this.rectangleLeft.Width); this.rectangleRight.Height = DrawingBoard.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 = DrawingBoard.Height - (rect.Height + this.rectangleTop.Height); this.ScreenBorder.Height = rect.Height; this.ScreenBorder.Width = rect.Width; Canvas.SetLeft(this.ScreenBorder, rect.X); Canvas.SetTop(this.ScreenBorder, rect.Y); } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } } /// <summary> /// 捕获屏幕 /// </summary> /// <returns></returns> private 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; } private void Btn_Click(object sender, RoutedEventArgs e) { try { Button button = sender as Button; switch (button.Name) { case "SaveBtn": if (IsFullScreen) { WrapPanelBtn.Visibility = Visibility.Collapsed; } ScreenBorder.Visibility = Visibility.Hidden; BitmapEncoder pngEncoder = new PngBitmapEncoder(); pngEncoder.Frames.Add(BitmapFrame.Create(CutBitmap())); // ImageSource 转 Bitmap System.Drawing.Bitmap bitmap = tools.ImageSourceToBitmap(pngEncoder.Frames[0]); // Bitmap 转 BitmapImage BitmapImage bitmapImage = tools.BitmapToBitmapImage(tools.GetPicThumbnail(bitmap,800,1270)); //BitmapImage 转 byte[] byte[] buffer = tools.BitmapImageToByteArray(bitmapImage); //清理资源 bitmapImage.StreamSource.Close(); bitmapImage.StreamSource.Dispose(); bitmapImage = null; //保存为文件 tools.SaveFile(@"E:\1.png", buffer); //UDP 发送 UDPSend.SendScreenFile(buffer); GC.Collect(); this.Close(); break; case "CancelBtn": this.Close(); break; default: break; } } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } } /// <summary> /// 裁剪图片 /// </summary> /// <returns></returns> private CroppedBitmap CutBitmap() { try { var renderTargetBitmap = new RenderTargetBitmap((int)DrawingBoard.Width, (int)DrawingBoard.Height, 96d, 96d, PixelFormats.Default); renderTargetBitmap.Render(DrawingBoard); return new CroppedBitmap(renderTargetBitmap, new Int32Rect((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height)); } catch (Exception ex) { WriteLog.WriteErrorInfo(ex); } return new CroppedBitmap(); } } }