C#图片裁剪方法(并保存到本地)
使用WPF
预览效果,分为xaml
前端界面和xaml.cs
逻辑实现
1.xaml前端界面文件
只是简单的布局设计,用于预览效果图
<Window x:Class="ScreenShortDemo.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:ScreenShortDemo"
mc:Ignorable="d" Loaded="Window_Loaded"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="45"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button x:Name="ScreenShortBtn" Content="截取" Height="32" Width="80" Click="ScreenShortBtn_Click" Margin="10,0"/>
<Button x:Name="SaveBtn" Content="保存" Height="32" Width="80" Click="SaveBtn_Click" Margin="10,0"/>
</StackPanel>
<UniformGrid Grid.Row="1" Columns="2" Background="LightBlue">
<Image x:Name="SourceImg" Margin="10"/>
<Image x:Name="AfterImg" Margin="10"/>
</UniformGrid>
</Grid>
</Window>
2.xaml.cs逻辑实现文件
引用dll
,System.Drawing.dll
文件,如果是.netframework
,直接在引用中添加,如果是.net core
项目或者.net 5.0
项目,需要添加nuget
包:System.Drawing.Common
截取和保存分为两个方法,分开实现,中间使用到了常用图片格式的转换,参考博客:图片文件格式转换【https://blog.youkuaiyun.com/qq_18995513/article/details/53693554】
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace ScreenShortDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//设置原图片
var bitmapImg = new BitmapImage(new System.Uri("pack://application:,,,/ScreenShortDemo;component/Resource/ecg.jpg"));
this.SourceImg.Source = bitmapImg;
}
/// <summary>
/// 截图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScreenShortBtn_Click(object sender, RoutedEventArgs e)
{
var imagesource = this.SourceImg.Source;
using(var bitmap = ImageSourceToBitmap(imagesource))
{
System.Drawing.Image img2 = ImageTailor(bitmap, 0, 0, 1025, 609, 75, 165,1030,609);
var bitmapImage = BitmapToBitmapImage(new System.Drawing.Bitmap(img2));
this.AfterImg.Source = bitmapImage;
};
}
/// <summary>
/// 保存
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveBtn_Click(object sender, RoutedEventArgs e)
{
var dialog = new System.Windows.Forms.FolderBrowserDialog();
dialog.Description = "请选择文件路径";
if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
return;
}
var foldPath = dialog.SelectedPath;
var source = this.AfterImg.Source;
var bitmapsource = source as BitmapSource;
SaveImageToFile(bitmapsource, System.IO.Path.Combine(foldPath,"test.jpg"));
}
/// <summary>
/// 图片截取
/// </summary>
/// <param name="bmp">原图像</param>
/// <param name="nowpoint_x">画布绘制起始点,x</param>
/// <param name="nowpoint_Y">画布绘制起始点,y</param>
/// <param name="nowWidth">画布宽度</param>
/// <param name="nowHeight">画布高度</param>
/// <param name="startpoint_x">截图起始点,x</param>
/// <param name="startpoint_Y">截图起始点,y</param>
/// <param name="screenWeight">截图宽度</param>
/// <param name="screenHeight">截图高度</param>
/// <returns>截取后图片,大小 nowWidth*nowHeight</returns>
public System.Drawing.Image ImageTailor(System.Drawing.Bitmap bmp,int nowpoint_x,int nowpoint_Y, int nowWidth, int nowHeight, int startpoint_x, int startpoint_Y,int screenWeight, int screenHeight)
{
var newbm = new System.Drawing.Bitmap(nowWidth, nowHeight);
using (var g = System.Drawing.Graphics.FromImage(newbm))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//前Rectangle代表画布大小,后Rectangle代表裁剪后右边留下的区域
g.DrawImage(bmp, new System.Drawing.Rectangle(nowpoint_x, nowpoint_Y, 1030, 608), new System.Drawing.Rectangle(startpoint_x, startpoint_Y, screenWeight, screenHeight), System.Drawing.GraphicsUnit.Pixel);
};
return newbm;
}
/// <summary>
/// ImageSource --> Bitmap
/// </summary>
/// <param name="imageSource"></param>
/// <returns></returns>
public System.Drawing.Bitmap ImageSourceToBitmap(ImageSource imageSource)
{
BitmapSource m = (BitmapSource)imageSource;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(m.PixelWidth, m.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); // 坑点:选Format32bppRgb将不带透明度
System.Drawing.Imaging.BitmapData data = bmp.LockBits(
new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
m.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);
return bmp;
}
/// <summary>
/// Bitmap --> BitmapImage
/// </summary>
/// <param name="bitmap"></param>
/// <returns></returns>
public BitmapImage BitmapToBitmapImage(System.Drawing.Bitmap bitmap)
{
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); // 坑点:格式选Bmp时,不带透明度
stream.Position = 0;
BitmapImage result = new BitmapImage();
result.BeginInit();
// According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
// Force the bitmap to load right now so we can dispose the stream.
result.CacheOption = BitmapCacheOption.OnLoad;
result.StreamSource = stream;
result.EndInit();
result.Freeze();
return result;
}
}
/// <summary>
/// 保存图片到文件
/// </summary>
/// <param name="image">图片数据</param>
/// <param name="filePath">保存路径</param>
private void SaveImageToFile(System.Windows.Media.Imaging.BitmapSource image, string filePath)
{
var encoder = GetBitmapEncoder(filePath);
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(image));
using (var stream = new FileStream(filePath, FileMode.Create))
{
encoder.Save(stream);
}
}
/// <summary>
/// 根据文件扩展名获取图片编码器
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>图片编码器</returns>
private System.Windows.Media.Imaging.BitmapEncoder GetBitmapEncoder(string filePath)
{
var extName = Path.GetExtension(filePath).ToLower();
if (extName.Equals(".png"))
{
return new System.Windows.Media.Imaging.PngBitmapEncoder();
}
else
{
return new System.Windows.Media.Imaging.JpegBitmapEncoder();
}
}
}
}