[WPF]图片裁切功能(鼠标绘制)
- 项目类型:WPF
- 项目语言:c#
- 项目框架:.Net5
1.主界面Xaml
<Window x:Class="WpfApp4.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:WpfApp4"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><DockPanel LastChildFill="True"><Grid DockPanel.Dock="Left" Width="200"><StackPanel><Button Content="选择图片" Click="Button_Click_1" Height="30" Margin="5" /><Button Content="绘制路径" Height="30" Margin="5" Click="Button_Click_2" /><Button Content="清空路径" Height="30" Margin="5" Click="Button_Click_5" /><Button Content="保存路径" Height="30" Margin="5" Click="Button_Click_3" /><Button Content="加载路径" Height="30" Margin="5" Click="Button_Click_4" /><!--<Button Content="确定范围" Height="30" Margin="5" Click="Button_Click_6" />--><Button Content="栽剪" Click="Button_Click" Height="30" Margin="5"/></StackPanel></Grid><Grid ><Grid.RowDefinitions><RowDefinition Height="auto"/><RowDefinition/></Grid.RowDefinitions><StackPanel><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="auto"/><ColumnDefinition/></Grid.ColumnDefinitions><Label Grid.Column="0" Content="文件路径"/><TextBox Grid.Column="1" x:Name="ui_filepath" IsReadOnly="True"/></Grid><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="auto"/><ColumnDefinition/></Grid.ColumnDefinitions><Label Grid.Column="0" Content="保存路径"/><TextBox Grid.Column="1" x:Name="ui_savepath" IsReadOnly="True"/></Grid></StackPanel><Grid Grid.Row="1"><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Border Grid.Column="0" ><Grid><Image Grid.Column="0" x:Name="ui_image_01"/><InkCanvas Grid.Column="0" x:Name="inkCanvas1" HorizontalAlignment="Stretch"MinWidth="100" MinHeight="100"Width="{Binding ElementName=ui_image_01,Path=ActualWidth}"Height="{Binding ElementName=ui_image_01,Path=ActualHeight}"Background="Transparent"></InkCanvas></Grid></Border><Image Grid.Column="1" x:Name="ui_image_02"/></Grid></Grid></DockPanel>
</Window>
2.主界面代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Reflection;
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.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;using Microsoft.Win32;using Point = System.Drawing.Point;namespace WpfApp4
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{//声明一个 DrawingAttributes 类型的变量DrawingAttributes drawingAttributes;public MainWindow(){InitializeComponent();inkCanvas1.EditingMode = InkCanvasEditingMode.None;drawingAttributes = new DrawingAttributes();inkCanvas1.DefaultDrawingAttributes = drawingAttributes;//设置 DrawingAttributes 的 Color 属性设置颜色drawingAttributes.Color = Colors.Red;var _dir = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);this.ui_filepath.Text = _dir;this.ui_savepath.Text = _dir;}private void Button_Click(object sender, RoutedEventArgs e){GraphicsPath path = new GraphicsPath();if (this.inkCanvas1.Strokes.Count != 0){var _xRate = (this.ui_image_01.Source as BitmapImage).PixelWidth / this.inkCanvas1.Width;var _yRate = (this.ui_image_01.Source as BitmapImage).PixelHeight / this.inkCanvas1.Height;var _list = new List<Point>();var _lastpoint = new Point(0, 0);foreach (var _stroke in this.inkCanvas1.Strokes){foreach (var _point in _stroke.StylusPoints){var _newpoint = new Point((int)(_point.X * _xRate), (int)(_point.Y * _yRate));if (Math.Abs(_newpoint.X - _lastpoint.X) < 5 && Math.Abs(_newpoint.Y - _lastpoint.Y) < 5) { continue; }_lastpoint = _newpoint;_list.Add(_newpoint);}}path.AddLines(_list.ToArray());}if (path.PointCount < 1) { return; }if (string.IsNullOrWhiteSpace(this.ui_filepath.Text)) { return; }Bitmap bit = (Bitmap)Bitmap.FromFile(this.ui_filepath.Text, false);BitmapCrop2(bit, path, out Bitmap newBit);newBit.Save(this.ui_savepath.Text);this.ui_image_02.Source = ByteArrayToBitmapImage(File.ReadAllBytes(this.ui_savepath.Text));}private void Button_Click_1(object sender, RoutedEventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog{InitialDirectory = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),Filter = @"Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg",FilterIndex = 3,RestoreDirectory = true};var _result = openFileDialog.ShowDialog();if (!_result.HasValue) { return; }if (_result == true){var _filename = openFileDialog.FileName;this.ui_filepath.Text = _filename;var _name = System.IO.Path.GetFileNameWithoutExtension(_filename);var _dir = System.IO.Path.GetDirectoryName(_filename);this.ui_savepath.Text = System.IO.Path.Combine(_dir, $"{_name}({DateTime.Now.ToString("yyyyMMddHHmmss")}).jpg");this.ui_image_01.Source = ByteArrayToBitmapImage(File.ReadAllBytes(this.ui_filepath.Text));this.ui_image_02.Source = null;}else{this.ui_filepath.Text = "";this.ui_savepath.Text = "";this.ui_image_01.Source = null;this.ui_image_02.Source = null;}}/// <summary>/// 图片截图/// </summary>/// <param name="bitmap">原图</param>/// <param name="path">裁剪路径</param>/// <param name="outputBitmap">输出图</param>/// <returns></returns>public static Bitmap BitmapCrop2(Bitmap bitmap, GraphicsPath path, out Bitmap outputBitmap){RectangleF rect = path.GetBounds();int left = (int)rect.Left;int top = (int)rect.Top;int width = (int)rect.Width;int height = (int)rect.Height;Bitmap image = (Bitmap)bitmap.Clone();outputBitmap = new Bitmap(width, height);for (int i = left; i < left + width; i++){for (int j = top; j < top + height; j++){//判断坐标是否在路径中 if (path.IsVisible(i, j)){//复制原图区域的像素到输出图片 outputBitmap.SetPixel(i - left, j - top, image.GetPixel(i, j));}}}bitmap.Dispose();return image;}public static BitmapImage ByteArrayToBitmapImage(byte[] byteArray){BitmapImage bmp = null;try{bmp = new BitmapImage();bmp.BeginInit();bmp.StreamSource = new MemoryStream(byteArray);bmp.EndInit();}catch{bmp = null;}return bmp;}private void Button_Click_2(object sender, RoutedEventArgs e){//绘制墨迹inkCanvas1.EditingMode = InkCanvasEditingMode.Ink;}private void Button_Click_3(object sender, RoutedEventArgs e){if (this.inkCanvas1.Strokes.Count != 0){SaveFileDialog save = new SaveFileDialog{InitialDirectory = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),FileName = $"路径{DateTime.Now.ToString("yyyyMMddHHmmss")}.isf",Filter = "文件|*.isf"};if (save.ShowDialog() == true){FileStream f = File.Open(save.FileName, FileMode.Create, FileAccess.Write);this.inkCanvas1.Strokes.Save(f);f.Close();}}this.inkCanvas1.Strokes = new System.Windows.Ink.StrokeCollection();}private void Button_Click_4(object sender, RoutedEventArgs e){if (this.inkCanvas1.Strokes.Count != 0){MessageBoxResult Message = MessageBox.Show("已修改是否保存?", "是否保存", MessageBoxButton.YesNo);//保存,新建if (Message == MessageBoxResult.Yes){this.Button_Click_3(sender, e);return;}}OpenFileDialog open = new OpenFileDialog{InitialDirectory = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),Title = "选择文件",Filter = "文件|*.isf"};if (open.ShowDialog() == true){FileStream f = File.Open(open.FileName, FileMode.Open, FileAccess.Read);this.inkCanvas1.Strokes = new System.Windows.Ink.StrokeCollection(f);f.Close();}}private void Button_Click_5(object sender, RoutedEventArgs e){this.inkCanvas1.Strokes.Clear();this.inkCanvas1.Strokes = new System.Windows.Ink.StrokeCollection();}}
}
3.效果图
3.1.启动
3.2.选择图片
3.3.绘制路径
3.4.剪切图片
[WPF]图片裁切功能(鼠标绘制)相关推荐
- 原型图Mockplus:怎样使用图片裁切功能
2019独角兽企业重金招聘Python工程师标准>>> 图片裁切功能就是裁掉图片中多余的或不需要的部分. https://www.mockplus.cn/skill/single/s ...
- 135编辑器图片裁切功能
公众号排版 可以直接对图片编辑? 那就是 135编辑器的图片裁剪功能 小编朋友们以后在编辑图片时 再也不用打开ps之类的工具进行编辑了 话不多说,大家往下看看怎么用吧 图片剪裁功能介绍 ✚ ● ○ 图 ...
- html鼠标悬浮更换图片,Vue.js鼠标悬浮更换图片功能
最近自己做的项目中设计师要求分类栏中鼠标悬停更换图片,大致实现出来的效果就是这样: 这个在jQuery中是个很简单的事,但是在vue中我还是第一次实现. 首先将所有的选中后图片都覆盖到没选中图片上 c ...
- html5给图片加圆圈,js+canvas制作的用鼠标绘制圆形图案,可叠加产生不同色
脚本代码(For Alixixi.com)如下: Document body{ font-family: 微软雅黑; } canvas{ display:block; border:1px dotte ...
- 原生js从零实现图片裁切
效果图 在我的上一篇文章已经介绍过如何实现图片压缩,本篇文章主要讲解在此基础上单独实现的图片裁剪功能. 点击选择文件上传一张图片,点击裁切时会出现裁剪框,移动或拉伸裁剪框会在下方生成裁剪后的图片.点击 ...
- php jcrop,PHP结合JQueryJcrop实现图片裁切实例详解
我们经常可以看到一些网站上有图片剪切的功能,或许你会觉得这一功能炫目华丽,神秘莫测!但是今天介绍的一款专用于图片裁切的插件jquery.Jcrop.min.js就将揭开图片剪切的神秘面纱.使用这个插件 ...
- WPF,强制捕获鼠标事件,鼠标移出控件外依然可以执行强制捕获的鼠标事件
在WPF中,只有鼠标位置在某个控件上的时候才会触发该控件的鼠标事件. 例如,有两个控件都注册了MouseDown和MouseUp事件,在控件1上按下鼠标,不要放开,移动到控件2上再放开. 在这个过程中 ...
- pythontkinter图片_Python tkinter实现图片标注功能(完整代码)
.tkinter tkinter是Python下面向tk的图形界面接口库,可以方便地进行图形界面设计和交互操作编程.tkinter的优点是简单易用.与Python的结合度好.tkinter在Pytho ...
- vue项目引入百度地图BMapGL鼠标绘制和BMap辅助工具
目录 引言 1.引用百度地图 2.在项目中使用百度地图 2-1.页面结构部分 2-2.js逻辑部分 3-1.页面结构部分 Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架.它旨 ...
- web图片裁切插件 cropper.js 详细介绍
cropper.js一个用来处理图片的插件,可以使用它来实现图片的各种模式下的裁切效果,当我们在做一个上传头像或者上传图片功能的时候,需要用户裁切出用户想要的图片位置就可以利用这个插件来实现','cr ...
最新文章
- python库下载安装网址
- matlab实现浮点转定点,浮点转定点方法总结.doc
- 玩转Android---事件监听篇---第2篇
- 营销管理手册_某连锁动物医院营销管理咨询项目方案成功汇报
- asp如何将图片文件上传到mysql数据库中_怎样才能利用ASP把图片上传到数据库
- ORACLE 常用函数——转换函数
- JavaScript设计模式入坑 1
- 【路径规划】基于matlab改进的人工势场算法机器人避障路径规划【含Matlab源码 1151期】
- 百度地图多点路线规划_自驾游路线规划神器:高德地图路书功能
- Web服务稳定性测试 负载测试 可靠性测试 方案 测试报告
- 手机屏幕材料区别 TFT和OLED
- 计算机程序员笔试题,历年计算机软考程序员笔试真题及答案
- 基础知识 | node js基础知识
- (转)四旋翼飞行器基本知识
- DDR SDRAM原理介绍
- php实现html转word
- 渗压计的使用安装方法
- Android在app中打开另一个app
- minio文件服务器的数据同步操作
- 【源码】iOS指纹解锁Touch ID的开发