C#图片裁剪方法(并保存到本地)

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逻辑实现文件

​ 引用dllSystem.Drawing.dll文件,如果是.netframework,直接在引用中添加,如果是.net core项目或者.net 5.0项目,需要添加nuget包:System.Drawing.Common

​ 截取和保存分为两个方法,分开实现,中间使用到了常用图片格式的转换,参考博客:图片文件格式转换【https://blog.csdn.net/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();
            }
        }
    }
}

3.效果展示

效果图

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值