FrmNImageViewer.cs 8.3 KB
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TSA_V.Common;

namespace TSA_V
{
    public partial class FrmNImageViewer : FrmBase
    {
        private string fileName = "";
        private bool update = false;
        public FrmNImageViewer(string fileName)
        {
            InitializeComponent();
            this.fileName = fileName;
        }

        private void FrmImageViewer_Load(object sender, EventArgs e)
        {
            if (fileName != null && File.Exists(fileName))
            {
                System.Drawing.Image img = System.Drawing.Image.FromFile(fileName);
                Bitmap myImage = new System.Drawing.Bitmap(img);
                this.picViewer.Image = myImage;

                img.Dispose();
                btnOK.Focus();
            }
        }

        private void BackFile()
        {

            string directory = Path.GetDirectoryName(fileName);
            string extension = Path.GetExtension(fileName);
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);

            // 构建新文件名为原文件名后加上后缀"back"
            string backStr = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");
            string newFileName = Path.Combine(directory, fileNameWithoutExtension + $"_{backStr}back" + extension);

            try
            {
                // 复制原图片到新文件名
                File.Copy(fileName, newFileName);
                LogUtil.info("备份原图片文件到:" + newFileName);
            }
            catch (Exception ex)
            {
                LogUtil.error("出现异常:" + ex.Message);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (update)
            {
                //备份原图
                BackFile();
                Image newImage = (Image)picViewer.Image.Clone();
                newImage.Save(fileName);
                LogUtil.info("保存修改后的图片:" + fileName);

            }
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void btnR_Click(object sender, EventArgs e)
        {
            int v = (int)numRValue.Value;

            // 旋转图片90度
            RotateImage(v);
        }
        //private void RotateImage(float angle)
        //{
        //    update = true;
        //    Image originalImage = (Image)picViewer.Image.Clone();
        //    // 创建一个新的 Bitmap 用于存储旋转后的图片
        //    Bitmap bmp = new Bitmap(originalImage.Width, originalImage.Height);

        //    // 设置绘图的旋转角度和中心点
        //    Graphics g = Graphics.FromImage(bmp);
        //    g.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
        //    g.RotateTransform(angle);
        //    g.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

        //    // 绘制旋转后的图片
        //    g.DrawImage(originalImage, new Point(0, 0));

        //    g.Dispose();

        //    // 更新 PictureBox 中的图片
        //    picViewer.Image = bmp;

        //    // 更新旋转后的图片
        //    //rotatedImage = bmp;
        //}
        private void RotateImage(float angle)
        {
            update = true;
            Image originalImage = (Image)picViewer.Image.Clone();

            // 计算旋转后包含整个图像的最小矩形
            RectangleF rotatedRect = new RectangleF(0, 0, originalImage.Width, originalImage.Height);
            PointF[] points = new PointF[] { new PointF(rotatedRect.Left, rotatedRect.Top), new PointF(rotatedRect.Right, rotatedRect.Top), new PointF(rotatedRect.Left, rotatedRect.Bottom) };
            Matrix matrix = new Matrix();
            matrix.RotateAt(angle, new PointF(rotatedRect.Width / 2, rotatedRect.Height / 2));
            matrix.TransformPoints(points);
            rotatedRect = RectangleF.FromLTRB(points.Min(p => p.X), points.Min(p => p.Y), points.Max(p => p.X), points.Max(p => p.Y));

            // 创建一个新的 Bitmap 用于存储旋转后的图片
            Bitmap bmp = new Bitmap((int)Math.Ceiling(rotatedRect.Width), (int)Math.Ceiling(rotatedRect.Height));

            // 设置绘图的旋转角度和中心点
            Graphics g = Graphics.FromImage(bmp);
            g.TranslateTransform(rotatedRect.Width / 2, rotatedRect.Height / 2);
            g.RotateTransform(angle);
            g.TranslateTransform(-originalImage.Width / 2, -originalImage.Height / 2);

            // 绘制旋转后的图片
            g.DrawImage(originalImage, new Point(0, 0));

            g.Dispose();

            // 更新 PictureBox 中的图片
            picViewer.Image = bmp;

            // 更新旋转后的图片
            //rotatedImage = bmp;
        }


        /// <summary>
        /// 获取单通道的掩模图片
        /// </summary>
        /// <param name="img"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public Image GetRoiMask(Image img, GraphicsPath path)
        {
            if (path != null)
            {
                //5GC.Collect();
                var bounds = path.GetBounds();
                if (bounds.Width > 0 && bounds.Height > 0)
                {
                    try
                    {
                        Bitmap mask = new Bitmap(img.Width, img.Height);
                        using (Graphics g = Graphics.FromImage(mask))
                        {
                            var br = new TextureBrush(img);
                            g.FillPath(br, path);
                            g.Dispose();
                        }
                        return mask;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                }
            }
            return null;
        }

        public Image CutImage(Image image, GraphicsPath path, bool needCut)
        {
            Image maskImg = GetRoiMask(image, path);
            if (maskImg != null)
            {
                var bounds = path.GetBounds();
                int resultWidth = (int)bounds.Width;
                int resultHeight = (int)bounds.Height;
                var srcLocation = bounds.Location;
                if (!needCut)
                {
                    //获取带原图位置的大图
                    resultWidth = image.Width;
                    resultHeight = image.Height;
                    srcLocation = PointF.Empty;
                }

                Bitmap result = new Bitmap(resultWidth, resultHeight);
                var dstRect = new RectangleF(0, 0, resultWidth, resultHeight);
                var srcRect = new RectangleF(srcLocation.X, srcLocation.Y, resultWidth, resultHeight);
                using (Graphics g = Graphics.FromImage(result))
                {
                    //g.Clear(Color.Transparent);
                    g.DrawImage(maskImg, dstRect, srcRect, GraphicsUnit.Pixel);
                    g.Dispose();
                }
                result.MakeTransparent(Color.White);
                return result;
            }
            return null;
        } 
        private void btnCut_Click(object sender, EventArgs e)
        {
            try
            {
                if (picViewer.SelectionRegion != null&&picViewer.SelectionRegion.PointCount>0)
                {
                    update = true;
                    GraphicsPath path = picViewer.SelectionRegion;
                    Image originalImage = (Image)picViewer.Image.Clone();
                    Image cutImage = CutImage(originalImage, path, true);
                    picViewer.Image = cutImage;
                    picViewer.SelectionRegion = null;
                }

            }
            catch (Exception ex)
            {
                LogUtil.error(ex.ToString());
                MessageBox.Show(ex.ToString());
            }
        }
    }
}