当前位置:网站首页>wpf实现简易画板功能(带截取画板,签名截图等等)
wpf实现简易画板功能(带截取画板,签名截图等等)
2022-08-09 11:09:00 【一头小驴】
参照自:https://www.cnblogs.com/jixin/p/4730170.html
https://blog.csdn.net/u012408847/article/details/86482399
截图功能将会把红色方块区域内的内容截取下来,保存在img文件夹中。
window1.xaml
<Window x:Class="_1_5GraphicsWpf.Window1"
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:_1_5GraphicsWpf"
xmlns:cvr="clr-namespace:_1_5GraphicsWpf.ControlValidationRule"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Grid>
<DockPanel Background="AliceBlue">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"></ColumnDefinition>
<ColumnDefinition Width="13*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Canvas Grid.Column="1" x:Name="myCanvas" DockPanel.Dock="Right" Background="LightGray"
PreviewMouseLeftButtonDown="Canvas_PreviewMouseLeftButtonDown" PreviewMouseMove="Canvas_PreviewMouseMove"
MouseLeftButtonUp="MyCanvas_MouseLeftButtonUp"
></Canvas>
<Grid DockPanel.Dock="Left" x:Name="LeftDockPanel">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30px"></RowDefinition>
<RowDefinition Height="30px"></RowDefinition>
<RowDefinition Height="30px"></RowDefinition>
<RowDefinition Height="30px"></RowDefinition>
<RowDefinition Height="30px"></RowDefinition>
<RowDefinition Height="30px"></RowDefinition>
<RowDefinition Height="30px"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0">颜色œ˜œ˜œ˜œ˜</Label>
<ComboBox x:Name="ComboColor" Grid.Row="0" Grid.Column="1" Margin="6 3"
SelectedValuePath="{Binding Path=ID}" SelectedIndex="{Binding Path=Combo_ColorIndex}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=PColor}"></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Column="0" Grid.Row="1">线条粗细œ˜œ˜œ˜œ˜</Label>
<TextBox x:Name="textBoxThick" Grid.Row="1" Grid.Column="1" Margin="6,3" >
<TextBox.Text>
<Binding Path="Thickness" NotifyOnValidationError="True" NotifyOnSourceUpdated="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<cvr:DataValidationRule ValidatesOnTargetUpdated="True"></cvr:DataValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<Slider Minimum="0" Maximum="100" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Value="{Binding Path=Thickness, Mode=TwoWay}"></Slider>
<Label Grid.Column="0" Grid.Row="3">样式œ˜œ˜œ˜œ˜</Label>
<ComboBox x:Name="ComboStyle" Grid.Row="3" Grid.Column="1" Margin="6 3"
SelectedValuePath="{Binding Path=ID}" SelectedIndex="{Binding Path=Combo_StyleIndex}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=PStyle}"></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Button Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Margin="10 3" Content="清除" Click="Button_Click"></Button>
<Button Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" Margin="10 3" Content="截图" Click="Button_Click_1"></Button>
</Grid>
</Grid>
</DockPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;
using _1_5GraphicsWpf.ViewModel;
using _1_5GraphicsWpf.ControlValidationRule;
using System.Drawing;
namespace _1_5GraphicsWpf
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Init();
}
ObservableCollection<VMColor> ColorCollection;
ObservableCollection<VMStyle> StyleCollection;
Global_Window1 GlobalVaries;
void Init()
{
ColorCollection = new ObservableCollection<VMColor> {
new VMColor{ID = 0,PColor="默认"},
new VMColor{ID = 1,PColor="红色"},
new VMColor{ID = 2,PColor="绿色" }
};
StyleCollection = new ObservableCollection<VMStyle> {
new VMStyle{ID = 0,PStyle="平坦"},
new VMStyle{ID = 1,PStyle="直角"},
new VMStyle{ID = 2,PStyle="三角"},
new VMStyle{ID = 3,PStyle="圆形"}
};
GlobalVaries = new Global_Window1() {
Combo_ColorIndex = 0,
Combo_StyleIndex = 0,
Thickness = 1
};
this.ComboColor.ItemsSource = ColorCollection;
this.ComboStyle.ItemsSource = StyleCollection;
this.DataContext = GlobalVaries;
this.textBoxThick.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(this.ValidationError));
}
void ValidationError(object sender,RoutedEventArgs e)
{
TextBox obj = sender as TextBox;
if (Validation.GetErrors(obj).Count>0)
{
obj.ToolTip = Validation.GetErrors(this.textBoxThick)[0].ErrorContent.ToString();
}
}
System.Windows.Point startPoint;
List<System.Windows.Point> pointList = new List<System.Windows.Point>();
private void Canvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(myCanvas);
}
private void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
// 返回指针相对于Canvas的位置
System.Windows.Point point = e.GetPosition(myCanvas);
if (pointList.Count == 0)
{
// 加入起始点
pointList.Add(new System.Windows.Point(this.startPoint.X, this.startPoint.Y));
}
else
{
// 加入移动过程中的point 颜色
pointList.Add(point);
}
// 去重复点
var disList = pointList.Distinct().ToList();
var count = disList.Count(); // 总点数
if (point != this.startPoint && this.startPoint != null)
{
var l = new Line();
//string color = (ComboColor.SelectedItem as ComboBoxItem).Content as string;
int color = int.Parse((ComboColor.SelectedValue as VMColor).ID.ToString());
switch (color)
{
case 0:
l.Stroke = System.Windows.Media.Brushes.Black;
break;
case 1:
l.Stroke = System.Windows.Media.Brushes.Red;
break;
case 2:
l.Stroke = System.Windows.Media.Brushes.Green;
break;
default:
l.Stroke = System.Windows.Media.Brushes.Black;
break;
}
int style = int.Parse((ComboStyle.SelectedValue as VMStyle).ID.ToString());
switch (style)
{
case 0:
l.StrokeDashCap = PenLineCap.Flat;
l.StrokeStartLineCap = PenLineCap.Flat;
l.StrokeEndLineCap = PenLineCap.Flat;
break;
case 1:
l.StrokeDashCap = PenLineCap.Square;
l.StrokeStartLineCap = PenLineCap.Square;
l.StrokeEndLineCap = PenLineCap.Square;
break;
case 2:
l.StrokeDashCap = PenLineCap.Triangle;
l.StrokeStartLineCap = PenLineCap.Triangle;
l.StrokeEndLineCap = PenLineCap.Triangle;
break;
case 3:
l.StrokeDashCap = PenLineCap.Round;
l.StrokeStartLineCap = PenLineCap.Round;
l.StrokeEndLineCap = PenLineCap.Round;
break;
default:
l.StrokeDashCap = PenLineCap.Round;
l.StrokeStartLineCap = PenLineCap.Round;
l.StrokeEndLineCap = PenLineCap.Round;
break;
}
//l.StrokeLineJoin = PenLineJoin.Round;
//l.StrokeStartLineCap = PenLineCap.Triangle;
l.StrokeThickness = this.GlobalVaries.Thickness ;
if (count < 2)
return;
l.X1 = disList[count - 2].X; // count-2 保证 line的起始点为点集合中的倒数第二个点。
l.Y1 = disList[count - 2].Y;
// 终点X,Y 为当前point的X,Y
l.X2 = point.X;
l.Y2 = point.Y;
myCanvas.Children.Add(l);
}
}
}
private void MyCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
pointList.Clear();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.myCanvas.Children.Clear();//清除
pointList.Clear();
}
#region 截图
public static Shape CreateShape()
{
//矩形区域
return new System.Windows.Shapes.Rectangle() { Fill = null, Stroke = System.Windows.Media.Brushes.Red, StrokeThickness = 1 };
//圆形区域
//return new System.Windows.Shapes.Ellipse() { Fill = null, Stroke = System.Windows.Media.Brushes.Red, StrokeThickness = 1 };
}
bool drawFlag = false;
Shape insertShape;
System.Windows.Point startPosition;
private void Mask_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
insertShape = CreateShape();
if (insertShape != null)
{
drawFlag = true;
Canvas board = sender as Canvas;
//board.Children.Clear();
startPosition = e.GetPosition(board);
insertShape.Opacity = 1;
Canvas.SetLeft(insertShape, e.GetPosition(board).X);
Canvas.SetTop(insertShape, e.GetPosition(board).Y);
board.Children.Add(insertShape);
}
}
private void image_MouseMove(object sender, MouseEventArgs e)
{
Canvas board = sender as Canvas;
if (drawFlag && insertShape != null)
{
if (e.GetPosition(board).X > startPosition.X)
{
insertShape.Width = e.GetPosition(board).X - startPosition.X;
//Canvas.SetRight(insertShape, startPosition.X);
}
else
{
insertShape.Width = startPosition.X - e.GetPosition(board).X;
Canvas.SetLeft(insertShape, e.GetPosition(board).X);
}
if (e.GetPosition(board).Y > startPosition.Y)
{
insertShape.Height = e.GetPosition(board).Y - startPosition.Y;
//Canvas.SetBottom(insertShape, startPosition.Y);
}
else
{
insertShape.Height = startPosition.Y - e.GetPosition(board).Y;
Canvas.SetTop(insertShape, e.GetPosition(board).Y);
}
}
}
private void Mask_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Canvas board = sender as Canvas;
System.Windows.Point position = board.PointToScreen(new System.Windows.Point(0, 0));
drawFlag = false;
int width = (int)insertShape.Width +150 ;
int height = (int)insertShape.Height +110 ;
System.Drawing.Size size = new System.Drawing.Size(width, height);
int startX = (e.GetPosition(board).X < startPosition.X) ? (int)e.GetPosition(board).X : (int)startPosition.X ;
int startY = (e.GetPosition(board).Y < startPosition.Y) ? (int)e.GetPosition(board).Y : (int)startPosition.Y ;
//int endX = (e.GetPosition(board).X > startPosition.X) ? (int)e.GetPosition(board).X + 10 : (int)startPosition.X + 10;
//int endY = (e.GetPosition(board).Y > startPosition.Y) ? (int)e.GetPosition(board).Y + 10 : (int)startPosition.Y + 10;
if (insertShape != null)
{
insertShape.Opacity = 1;
System.Windows.Point p = e.GetPosition(board);
//BitmapSource memory = new Bitmap(width, height);
//Graphics g = Graphics.FromImage(memory);
//g.CopyFromScreen(this.Location.X + 1, this.Location.Y + 1, 0, 0, new System.Drawing.Size(width, height));
Clipboard.SetImage(memory);//把图片放到剪切板中
//bmp.Save("C:\\Screenshots\\" + filename);
using (Bitmap bmp = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
String filename = "ScreenCapture-" + DateTime.Now.ToString("ddMMyyyy-hhmmss") + ".png";
g.CopyFromScreen(startX+(int)position.X, startY+(int)position.Y, 0, 0, size);
bmp.Save("..\\..\\img\\" + filename);
Button_Click_2();
}
}
}
}
#endregion
bool canShot = false;
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.myCanvas.MouseLeftButtonDown += Mask_MouseLeftButtonDown;
this.myCanvas.MouseMove += image_MouseMove;
this.myCanvas.MouseLeftButtonUp += Mask_MouseLeftButtonUp;
this.myCanvas.PreviewMouseLeftButtonDown -= Canvas_PreviewMouseLeftButtonDown;
this.myCanvas.PreviewMouseMove -= Canvas_PreviewMouseMove;
this.myCanvas.MouseLeftButtonUp -= MyCanvas_MouseLeftButtonUp;
canShot = true;
}
private void Button_Click_2()
{
if (canShot ==true)
{
this.myCanvas.MouseLeftButtonDown -= Mask_MouseLeftButtonDown;
this.myCanvas.MouseMove -= image_MouseMove;
this.myCanvas.MouseLeftButtonUp -= Mask_MouseLeftButtonUp;
this.myCanvas.PreviewMouseLeftButtonDown += Canvas_PreviewMouseLeftButtonDown;
this.myCanvas.PreviewMouseMove += Canvas_PreviewMouseMove;
this.myCanvas.MouseLeftButtonUp += MyCanvas_MouseLeftButtonUp;
}
canShot = false;
}
}
}
边栏推荐
猜你喜欢
随机推荐
fork creates multiple child processes
排序--快排(图解)
uni-app 自带的picker封装一个日期-时间选择器
依赖注入(Dependency Injection)框架是如何实现的
prometheus接入mysqld_exporter
TensorFlow: NameError: name 'input_data' is not defined
Qt读写.ini配置文件
∘(空心的点乘)的数学含义
UNIX Philosophy
FreeRTOS列表和列表项源码分析
String类型的字符串对象转实体类和String类型的Array转List
Error: Cannot find module ‘./application‘
学习阶段总结(背包问题)
获取指定年度所有周的工具类
Paper Sharing | ACL2022 | Argument Relation Extraction Based on Transfer Learning
wait系统调用
STM32启动方式及BootLoader
CAN总线发送数据
Solve 1. tensorflow runs using CPU but not GPU 2. GPU version number in tensorflow environment 3. Correspondence between tensorflow and cuda and cudnn versions 4. Check cuda and cudnn versions
UNIX哲学









