improve:插入图片

This commit is contained in:
2025-07-31 10:27:19 +08:00
parent 78f8d9a271
commit a2dfa55dbd
5 changed files with 422 additions and 37 deletions
@@ -22,13 +22,20 @@
<!-- 选择区域容器 -->
<Canvas Name="SelectionCanvas">
<!-- 选择区域 -->
<!-- 矩形选择模式 -->
<Rectangle Name="SelectionRectangle"
Stroke="Red"
StrokeThickness="2"
Fill="Transparent"
Visibility="Collapsed" />
<!-- 任意形状选择模式 -->
<Path Name="SelectionPath"
Stroke="Red"
StrokeThickness="2"
Fill="Transparent"
Visibility="Collapsed" />
<!-- 尺寸信息显示 -->
<Border Name="SizeInfoBorder"
Background="Black"
@@ -43,6 +50,29 @@
</Border>
</Canvas>
<!-- 模式切换按钮 -->
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="0,100,0,0">
<Button Name="RectangleModeButton"
Content="矩形模式"
Margin="5,0"
Padding="10,5"
Background="#2563eb"
Foreground="White"
BorderThickness="0"
Click="RectangleModeButton_Click" />
<Button Name="FreehandModeButton"
Content="自由绘制"
Margin="5,0"
Padding="10,5"
Background="#6b7280"
Foreground="White"
BorderThickness="0"
Click="FreehandModeButton_Click" />
</StackPanel>
<!-- 提示文字 -->
<Border Background="Black"
Opacity="0.8"
@@ -50,9 +80,9 @@
Padding="15,8"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="0,50,0,0">
Margin="0,150,0,0">
<TextBlock Name="HintText"
Text="拖拽鼠标选择截图区域,按ESC取消"
Text="拖拽鼠标选择矩形区域,或使用自由绘制模式"
Foreground="White"
FontSize="16" />
</Border>
@@ -1,22 +1,33 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Brushes = System.Windows.Media.Brushes;
using Color = System.Windows.Media.Color;
// 为了避免命名冲突,使用别名
using WpfCanvas = System.Windows.Controls.Canvas;
using DrawingRectangle = System.Drawing.Rectangle;
using WpfRectangle = System.Windows.Shapes.Rectangle;
namespace Ink_Canvas
{
public partial class ScreenshotSelectorWindow : Window
{
private bool _isSelecting = false;
private bool _isFreehandMode = false;
private System.Windows.Point _startPoint;
private System.Windows.Point _currentPoint;
private List<System.Windows.Point> _freehandPoints;
private Polyline _freehandPolyline;
public Rectangle? SelectedArea { get; private set; }
public DrawingRectangle? SelectedArea { get; private set; }
public List<System.Windows.Point> SelectedPath { get; private set; }
public ScreenshotSelectorWindow()
{
@@ -25,9 +36,12 @@ namespace Ink_Canvas
// 设置窗口覆盖所有屏幕
SetupFullScreenOverlay();
// 初始化自由绘制模式
InitializeFreehandMode();
// 隐藏提示文字的定时器
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(3);
timer.Interval = TimeSpan.FromSeconds(5);
timer.Tick += (s, e) =>
{
HintText.Visibility = Visibility.Collapsed;
@@ -35,6 +49,18 @@ namespace Ink_Canvas
};
timer.Start();
}
private void InitializeFreehandMode()
{
_freehandPoints = new List<System.Windows.Point>();
_freehandPolyline = new Polyline
{
Stroke = Brushes.Red,
StrokeThickness = 2,
Fill = Brushes.Transparent
};
SelectionCanvas.Children.Add(_freehandPolyline);
}
private void SetupFullScreenOverlay()
{
@@ -66,10 +92,38 @@ namespace Ink_Canvas
{
// 取消截图
SelectedArea = null;
SelectedPath = null;
DialogResult = false;
Close();
}
}
private void RectangleModeButton_Click(object sender, RoutedEventArgs e)
{
_isFreehandMode = false;
RectangleModeButton.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); // 蓝色
FreehandModeButton.Background = new SolidColorBrush(Color.FromRgb(107, 114, 128)); // 灰色
HintText.Text = "拖拽鼠标选择矩形区域";
// 清除自由绘制的内容
_freehandPoints.Clear();
_freehandPolyline.Points.Clear();
SelectionPath.Visibility = Visibility.Collapsed;
SelectionRectangle.Visibility = Visibility.Collapsed;
}
private void FreehandModeButton_Click(object sender, RoutedEventArgs e)
{
_isFreehandMode = true;
FreehandModeButton.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); // 蓝色
RectangleModeButton.Background = new SolidColorBrush(Color.FromRgb(107, 114, 128)); // 灰色
HintText.Text = "按住鼠标左键绘制任意形状,松开完成";
// 清除矩形选择的内容
SelectionRectangle.Visibility = Visibility.Collapsed;
_freehandPoints.Clear();
_freehandPolyline.Points.Clear();
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
@@ -80,14 +134,28 @@ namespace Ink_Canvas
// 隐藏提示文字
HintText.Visibility = Visibility.Collapsed;
// 显示选择矩形
SelectionRectangle.Visibility = Visibility.Visible;
SizeInfoBorder.Visibility = Visibility.Visible;
if (_isFreehandMode)
{
// 自由绘制模式
_freehandPoints.Clear();
_freehandPolyline.Points.Clear();
_freehandPoints.Add(_startPoint);
_freehandPolyline.Points.Add(_startPoint);
}
else
{
// 矩形模式
SelectionRectangle.Visibility = Visibility.Visible;
SizeInfoBorder.Visibility = Visibility.Visible;
}
// 捕获鼠标
CaptureMouse();
UpdateSelection();
if (!_isFreehandMode)
{
UpdateSelection();
}
}
private void Window_MouseMove(object sender, MouseEventArgs e)
@@ -95,7 +163,18 @@ namespace Ink_Canvas
if (_isSelecting)
{
_currentPoint = e.GetPosition(this);
UpdateSelection();
if (_isFreehandMode)
{
// 自由绘制模式:添加点到路径
_freehandPoints.Add(_currentPoint);
_freehandPolyline.Points.Add(_currentPoint);
}
else
{
// 矩形模式
UpdateSelection();
}
}
}
@@ -106,27 +185,62 @@ namespace Ink_Canvas
_isSelecting = false;
ReleaseMouseCapture();
// 计算选择区域
var rect = GetSelectionRectangle();
if (rect.Width > 5 && rect.Height > 5) // 最小尺寸检查
if (_isFreehandMode)
{
// 转换为屏幕坐标,考虑DPI缩放
var dpiScale = GetDpiScale();
var virtualScreen = System.Windows.Forms.SystemInformation.VirtualScreen;
// 计算实际屏幕坐标
int screenX = (int)((rect.X * dpiScale) + virtualScreen.Left);
int screenY = (int)((rect.Y * dpiScale) + virtualScreen.Top);
int screenWidth = (int)(rect.Width * dpiScale);
int screenHeight = (int)(rect.Height * dpiScale);
SelectedArea = new Rectangle(screenX, screenY, screenWidth, screenHeight);
DialogResult = true;
// 自由绘制模式:完成路径
if (_freehandPoints.Count > 3) // 至少需要3个点形成有效路径
{
// 闭合路径
_freehandPoints.Add(_startPoint);
_freehandPolyline.Points.Add(_startPoint);
// 保存选择的路径
SelectedPath = new List<System.Windows.Point>(_freehandPoints);
// 计算边界矩形用于截图
var bounds = CalculatePathBounds(_freehandPoints);
var dpiScale = GetDpiScale();
var virtualScreen = System.Windows.Forms.SystemInformation.VirtualScreen;
int screenX = (int)((bounds.X * dpiScale) + virtualScreen.Left);
int screenY = (int)((bounds.Y * dpiScale) + virtualScreen.Top);
int screenWidth = (int)(bounds.Width * dpiScale);
int screenHeight = (int)(bounds.Height * dpiScale);
SelectedArea = new DrawingRectangle(screenX, screenY, screenWidth, screenHeight);
DialogResult = true;
}
else
{
SelectedArea = null;
SelectedPath = null;
DialogResult = false;
}
}
else
{
SelectedArea = null;
DialogResult = false;
// 矩形模式
var rect = GetSelectionRectangle();
if (rect.Width > 5 && rect.Height > 5) // 最小尺寸检查
{
// 转换为屏幕坐标,考虑DPI缩放
var dpiScale = GetDpiScale();
var virtualScreen = System.Windows.Forms.SystemInformation.VirtualScreen;
// 计算实际屏幕坐标
int screenX = (int)((rect.X * dpiScale) + virtualScreen.Left);
int screenY = (int)((rect.Y * dpiScale) + virtualScreen.Top);
int screenWidth = (int)(rect.Width * dpiScale);
int screenHeight = (int)(rect.Height * dpiScale);
SelectedArea = new DrawingRectangle(screenX, screenY, screenWidth, screenHeight);
DialogResult = true;
}
else
{
SelectedArea = null;
DialogResult = false;
}
}
Close();
@@ -164,5 +278,26 @@ namespace Ink_Canvas
return new Rect(x, y, width, height);
}
private Rect CalculatePathBounds(List<System.Windows.Point> points)
{
if (points == null || points.Count == 0)
return new Rect();
double minX = points[0].X;
double minY = points[0].Y;
double maxX = points[0].X;
double maxY = points[0].Y;
foreach (var point in points)
{
minX = Math.Min(minX, point.X);
minY = Math.Min(minY, point.Y);
maxX = Math.Max(maxX, point.X);
maxY = Math.Max(maxY, point.Y);
}
return new Rect(minX, minY, maxX - minX, maxY - minY);
}
}
}