FrmNImageViewer.cs 8.6 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 Image lastImage = null;
        private int LastWidth = 0;
        private int LastHeight = 0;
        private float targetAngle = 0;

        /// <summary>
        /// 选择图片的方式0=新增电路板。1=元器件图片
        /// </summary>
        public int  SelType=0;
        public FrmNImageViewer(string fileName,int type=0)
        {
            InitializeComponent();
            this.fileName = fileName;
            this.SelType = type;
        }

        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);

                lastImage = myImage;
                this.picViewer.Image = myImage;
                lastImage =(Image) myImage.Clone();
                LastWidth = lastImage.Width;
                LastHeight= lastImage.Height;
                targetAngle = 0;
                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)
            {
                if (SelType == 0)
                { 
                    //备份原图
                    BackFile();
                    Image newImage = (Image)picViewer.Image.Clone();
                    lastImage = newImage;
                    newImage.Save(fileName);
                    LogUtil.info("保存修改后的图片:" + fileName);
                }
                else
                {
                    Image newImage = (Image)picViewer.Image.Clone();
                    lastImage = newImage;

                    LogUtil.info($"SelType={SelType}不需要保存图片");
                }

            }
            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)
        {
            targetAngle += angle;
            
            update = true;
            //Image originalImage = (Image)picViewer.Image.Clone();
            Image originalImage = (Image)lastImage.Clone();

            // 计算旋转后包含整个图像的最小矩形
            RectangleF rotatedRect = new RectangleF(0, 0,LastWidth, LastHeight);
            //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), new PointF(rotatedRect.Right, rotatedRect.Bottom) };
            Matrix matrix = new Matrix();
            float pointA = targetAngle % 360;
            matrix.RotateAt(pointA, 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(pointA);
            g.TranslateTransform(-originalImage.Width / 2, -originalImage.Height / 2);

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

            g.Dispose();

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

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

         
        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;

                    lastImage = (Image)cutImage.Clone();
                    LastWidth = lastImage.Width;
                    LastHeight = lastImage.Height;
                    targetAngle = 0;
                }

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