首页 > 编程语言 >C# 简易图像处理(包括平移,旋转,翻转, 裁切)

C# 简易图像处理(包括平移,旋转,翻转, 裁切)

时间:2024-04-01 10:37:48浏览次数:20  
标签:currentPictureBox 裁切 C# System Forms Windows 图像处理 Location new

控件布局 主要分为一个Panel + 一个PictureBox + 还有一个自定义半透明裁切平面ExtendedPanel;

Form1.Designer.cs代码如下:

namespace ImageEditer
{
    partial class ImageEdit
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.splitContainer = new System.Windows.Forms.SplitContainer();
            this.imageList = new System.Windows.Forms.Panel();
            this.imageContainer = new System.Windows.Forms.Panel();
            this.optPanel = new System.Windows.Forms.Panel();
            this.reset = new System.Windows.Forms.Button();
            this.rota180 = new System.Windows.Forms.Button();
            this.rotaLeft = new System.Windows.Forms.Button();
            this.rota90 = new System.Windows.Forms.Button();
            this.roatRight = new System.Windows.Forms.Button();
            this.vertical = new System.Windows.Forms.Button();
            this.clip = new System.Windows.Forms.Button();
            this.mirror = new System.Windows.Forms.Button();
            this.ImageBox = new System.Windows.Forms.Panel();
            this.pictureBox = new System.Windows.Forms.PictureBox();
            this.clipPanel = new ImageEditer.ExtendedPanel();
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
            this.splitContainer.Panel1.SuspendLayout();
            this.splitContainer.Panel2.SuspendLayout();
            this.splitContainer.SuspendLayout();
            this.imageContainer.SuspendLayout();
            this.optPanel.SuspendLayout();
            this.ImageBox.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
            this.SuspendLayout();
            // 
            // splitContainer
            // 
            this.splitContainer.BackColor = System.Drawing.Color.Transparent;
            this.splitContainer.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
            this.splitContainer.Location = new System.Drawing.Point(0, 0);
            this.splitContainer.Margin = new System.Windows.Forms.Padding(0);
            this.splitContainer.Name = "splitContainer";
            // 
            // splitContainer.Panel1
            // 
            this.splitContainer.Panel1.Controls.Add(this.imageList);
            // 
            // splitContainer.Panel2
            // 
            this.splitContainer.Panel2.Controls.Add(this.imageContainer);
            this.splitContainer.Panel2MinSize = 100;
            this.splitContainer.Size = new System.Drawing.Size(961, 480);
            this.splitContainer.SplitterDistance = 236;
            this.splitContainer.SplitterWidth = 6;
            this.splitContainer.TabIndex = 0;
            // 
            // imageList
            // 
            this.imageList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.imageList.Location = new System.Drawing.Point(0, 0);
            this.imageList.Name = "imageList";
            this.imageList.Size = new System.Drawing.Size(232, 476);
            this.imageList.TabIndex = 1;
            // 
            // imageContainer
            // 
            this.imageContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.imageContainer.AutoScroll = true;
            this.imageContainer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));
            this.imageContainer.Controls.Add(this.optPanel);
            this.imageContainer.Controls.Add(this.ImageBox);
            this.imageContainer.ForeColor = System.Drawing.SystemColors.ControlText;
            this.imageContainer.Location = new System.Drawing.Point(0, 0);
            this.imageContainer.Name = "imageContainer";
            this.imageContainer.Size = new System.Drawing.Size(713, 476);
            this.imageContainer.TabIndex = 0;
            // 
            // optPanel
            // 
            this.optPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.optPanel.BackColor = System.Drawing.Color.Gray;
            this.optPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.optPanel.Controls.Add(this.reset);
            this.optPanel.Controls.Add(this.rota180);
            this.optPanel.Controls.Add(this.rotaLeft);
            this.optPanel.Controls.Add(this.rota90);
            this.optPanel.Controls.Add(this.roatRight);
            this.optPanel.Controls.Add(this.vertical);
            this.optPanel.Controls.Add(this.clip);
            this.optPanel.Controls.Add(this.mirror);
            this.optPanel.Location = new System.Drawing.Point(0, 0);
            this.optPanel.Name = "optPanel";
            this.optPanel.Size = new System.Drawing.Size(713, 26);
            this.optPanel.TabIndex = 2;
            // 
            // reset
            // 
            this.reset.Location = new System.Drawing.Point(1, 0);
            this.reset.Name = "reset";
            this.reset.Size = new System.Drawing.Size(60, 23);
            this.reset.TabIndex = 3;
            this.reset.Text = "复位";
            this.reset.UseVisualStyleBackColor = true;
            // 
            // rota180
            // 
            this.rota180.Location = new System.Drawing.Point(412, 0);
            this.rota180.Name = "rota180";
            this.rota180.Size = new System.Drawing.Size(72, 23);
            this.rota180.TabIndex = 9;
            this.rota180.Text = "旋转180°";
            this.rota180.UseVisualStyleBackColor = true;
            // 
            // rotaLeft
            // 
            this.rotaLeft.Location = new System.Drawing.Point(64, 0);
            this.rotaLeft.Name = "rotaLeft";
            this.rotaLeft.Size = new System.Drawing.Size(60, 23);
            this.rotaLeft.TabIndex = 1;
            this.rotaLeft.Text = "左旋";
            this.rotaLeft.UseVisualStyleBackColor = true;
            // 
            // rota90
            // 
            this.rota90.Location = new System.Drawing.Point(346, 0);
            this.rota90.Name = "rota90";
            this.rota90.Size = new System.Drawing.Size(63, 23);
            this.rota90.TabIndex = 8;
            this.rota90.Text = "旋转90°";
            this.rota90.UseVisualStyleBackColor = true;
            // 
            // roatRight
            // 
            this.roatRight.Location = new System.Drawing.Point(127, 0);
            this.roatRight.Name = "roatRight";
            this.roatRight.Size = new System.Drawing.Size(60, 23);
            this.roatRight.TabIndex = 2;
            this.roatRight.Text = "右旋";
            this.roatRight.UseVisualStyleBackColor = true;
            // 
            // vertical
            // 
            this.vertical.Location = new System.Drawing.Point(268, 0);
            this.vertical.Name = "vertical";
            this.vertical.Size = new System.Drawing.Size(75, 23);
            this.vertical.TabIndex = 7;
            this.vertical.Text = "垂直翻转";
            this.vertical.UseVisualStyleBackColor = true;
            // 
            // clip
            // 
            this.clip.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
            this.clip.Location = new System.Drawing.Point(487, 0);
            this.clip.Name = "clip";
            this.clip.Size = new System.Drawing.Size(68, 23);
            this.clip.TabIndex = 4;
            this.clip.Text = "裁切图像";
            this.clip.UseVisualStyleBackColor = true;
            // 
            // mirror
            // 
            this.mirror.Location = new System.Drawing.Point(190, 0);
            this.mirror.Name = "mirror";
            this.mirror.Size = new System.Drawing.Size(75, 23);
            this.mirror.TabIndex = 6;
            this.mirror.Text = "水平翻转";
            this.mirror.UseVisualStyleBackColor = true;
            // 
            // ImageBox
            // 
            this.ImageBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.ImageBox.AutoScroll = true;
            this.ImageBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
            this.ImageBox.Controls.Add(this.clipPanel);
            this.ImageBox.Controls.Add(this.pictureBox);
            this.ImageBox.Location = new System.Drawing.Point(0, 23);
            this.ImageBox.Name = "ImageBox";
            this.ImageBox.Size = new System.Drawing.Size(713, 455);
            this.ImageBox.TabIndex = 5;
            // 
            // pictureBox
            // 
            this.pictureBox.BackColor = System.Drawing.Color.Transparent;
            this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBox.Location = new System.Drawing.Point(3, 6);
            this.pictureBox.Margin = new System.Windows.Forms.Padding(0);
            this.pictureBox.Name = "pictureBox";
            this.pictureBox.Size = new System.Drawing.Size(59, 49);
            this.pictureBox.TabIndex = 0;
            this.pictureBox.TabStop = false;
            // 
            // clipPanel
            // 
            this.clipPanel.BackColor = System.Drawing.Color.Transparent;
            this.clipPanel.Cursor = System.Windows.Forms.Cursors.Default;
            this.clipPanel.Location = new System.Drawing.Point(80, 9);
            this.clipPanel.Name = "clipPanel";
            this.clipPanel.Size = new System.Drawing.Size(45, 41);
            this.clipPanel.TabIndex = 1;
            // 
            // ImageEdit
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(961, 480);
            this.Controls.Add(this.splitContainer);
            this.Name = "ImageEdit";
            this.Text = "图像";
            this.SizeChanged += new System.EventHandler(this.ImageEdit_ResizeBegin);
            this.splitContainer.Panel1.ResumeLayout(false);
            this.splitContainer.Panel2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
            this.splitContainer.ResumeLayout(false);
            this.imageContainer.ResumeLayout(false);
            this.optPanel.ResumeLayout(false);
            this.ImageBox.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.SplitContainer splitContainer;
        private System.Windows.Forms.Panel imageContainer;
        private System.Windows.Forms.Button rotaLeft;
        private System.Windows.Forms.Button roatRight;
        private System.Windows.Forms.Button reset;
        private System.Windows.Forms.Button clip;
        private System.Windows.Forms.Panel ImageBox;
        private System.Windows.Forms.Panel imageList;
        private System.Windows.Forms.PictureBox pictureBox;
        private ExtendedPanel clipPanel;
        private System.Windows.Forms.Button vertical;
        private System.Windows.Forms.Button mirror;
        private System.Windows.Forms.Button rota90;
        private System.Windows.Forms.Button rota180;
        private System.Windows.Forms.Panel optPanel;
    }
}

自定义半透明裁切平面ExtendedPanel代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ImageEditer
{
    internal class ExtendedPanel : Panel
    {

        private const int WS_EX_TRANSPARENT = 0x20;

        public ExtendedPanel()
        {
            SetStyle(ControlStyles.Opaque, true);
        }

        private int opacity = 50;
        [DefaultValue(50)]
        public int Opacity
        {
            get
            {
                return this.opacity;
            }
            set
            {
                if (value < 0 || value > 100)
                    throw new ArgumentException("value must be between 0 and 100");
                this.opacity = value;
            }
        }
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle = cp.ExStyle | WS_EX_TRANSPARENT;
                return cp;
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            using (var brush = new SolidBrush(Color.FromArgb(this.opacity * 255 / 100, this.BackColor)))
            {
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
                e.Graphics.DrawRectangle(new Pen(Color.Red, 2), this.ClientRectangle);
            }
            base.OnPaint(e);
        }

    }
}

图片的缩放、平移操作PictureBox,图片的旋转,镜像主要操作 PictureBox里的Image,图片的裁切主要通过操作自定义的ExtendedPanel大小来计算裁切后的尺寸及位置,通过转换计算PictureBox里的Image真实裁切尺寸。

主代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;

namespace ImageEditer
{
    public partial class ImageEdit : Form
    {
        private static int rotaNum = 0; // 旋转角度
        private static float zoomNum = 1.0f; // 缩放比例 未使用
        private static int pointRadis = 12; // 裁切点大小
        private static Boolean clipMode = false; // 是否开启裁切

        private static Pen rotaPen = new Pen(Color.Blue, 10); // 旋转颜色 未使用
        private static Pen clipPen = new Pen(Color.Red, 10); // 裁切颜色

        private static string imagePath = null; // 图像路径
        private static Image sourceImage = null; // 初始输入图像源
        private static Image outputImage = null; // 初始输出图像源 未使用

        private static PictureBox currentPictureBox = null; // 当前图像容器
        private static Panel currentImageBox = null; // 当前图像panel
        private static Panel currentClipPanel = null; // 裁切平面

        private static Point one = new Point(0, 0);  // 裁切调整坐标1
        private static Point two = new Point(0, 0);  // 裁切调整坐标2
        private static Point three = new Point(0, 0);  // 裁切调整坐标3
        private static Point four = new Point(0, 0);  // 裁切调整坐标4

        private static PictureBox OneButton = new PictureBox(); // 裁切调整点1
        private static PictureBox TwoButton = new PictureBox(); // 裁切调整点2
        private static PictureBox ThreeButton = new PictureBox(); // 裁切调整点3
        private static PictureBox FourButton = new PictureBox(); // 裁切调整点4

        private static System.Drawing.Rectangle clipRect = new System.Drawing.Rectangle(0, 0, 0, 0); // 裁切矩形信息

        public Point mouseDownPoint; // 记录鼠标点击坐标
        public bool isSelected = false; // 是否点击图像
        public bool isClicked = false; // 是否点击裁切矩形
        public bool isClickedOne = false; // 是否点解裁切矩形调整点1
        public bool isClickedTwo = false; // 是否点解裁切矩形调整点2
        public bool isClickedThree = false; // 是否点解裁切矩形调整点3
        public bool isClickedFour = false; // 是否点解裁切矩形调整点4

        public ImageEdit(){
           InitializeComponent();
           imagePath = @"D:\1.jpg";
           this.init(this.ImageBox, this.pictureBox, imagePath);
        }
        /**
         * 初始化组件及事件
         */
        public void init(Panel currentImage, PictureBox pictureBox, string path) {
            
            imagePath = path.Trim();
            sourceImage = Image.FromFile(path);
            currentImageBox = currentImage;

            /************************按钮事件**************************/
            this.reset.Click += new System.EventHandler(this.reset_Click);
            this.rotaLeft.Click += new System.EventHandler(this.roatleft_Click);
            this.roatRight.Click += new System.EventHandler(this.roatRight_Click);
            this.rota90.Click += new System.EventHandler(this.roat90_Click);
            this.rota180.Click += new System.EventHandler(this.roat180_Click);
            this.mirror.Click += new System.EventHandler(this.mirror_Click);
            this.vertical.Click += new System.EventHandler(this.vertical_Click);
            this.clip.Click += new System.EventHandler(this.clip_Click);

            currentPictureBox = pictureBox;
            currentPictureBox.Location = new Point(0, 0);
            currentPictureBox.Width = 0;
            currentPictureBox.Height = 0;
            currentPictureBox.Image = sourceImage;
            currentPictureBox.Width = sourceImage.Width;
            currentPictureBox.Height = sourceImage.Height;
            currentPictureBox.SizeMode = PictureBoxSizeMode.Zoom;

            this.SizeChanged += new EventHandler(this.ImageEdit_ResizeBegin);
            currentPictureBox.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseWheel);
            currentPictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseDown);
            currentPictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseMove);
            currentPictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox_MouseUp);

            /************************裁切框组件**************************/
           
            OneButton.Size = new Size(pointRadis, pointRadis);
            TwoButton.Size = new Size(pointRadis, pointRadis);
            ThreeButton.Size = new Size(pointRadis, pointRadis);
            FourButton.Size = new Size(pointRadis, pointRadis);

            OneButton.BackColor = Color.Red;
            TwoButton.BackColor = Color.Red;
            ThreeButton.BackColor = Color.Red;
            FourButton.BackColor = Color.Red;
            OneButton.Visible = clipMode;
            TwoButton.Visible = clipMode;
            ThreeButton.Visible = clipMode;
            FourButton.Visible = clipMode;
            FourButton.TabIndex = 10000;

            currentImageBox.Controls.Add(OneButton);
            currentImageBox.Controls.Add(TwoButton);
            currentImageBox.Controls.Add(ThreeButton);
            currentImageBox.Controls.Add(FourButton);
            currentImageBox.Controls.Add(pictureBox);

            currentClipPanel = this.clipPanel;
            currentClipPanel.BackColor = Color.Transparent;
            currentClipPanel.Visible = false;
            currentClipPanel.Location = new Point(0, 0);
            currentClipPanel.Width = 0;
            currentClipPanel.Height = 0;

            currentClipPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.clip_MouseDown);
            currentClipPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.clip_MouseMove);
            currentClipPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.clip_MouseUp);

            OneButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.One_MouseDown);
            OneButton.MouseMove += new System.Windows.Forms.MouseEventHandler(this.One_MouseMove);
            OneButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.One_MouseUp);

            TwoButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Two_MouseDown);
            TwoButton.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Two_MouseMove);
            TwoButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Two_MouseUp);

            ThreeButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Three_MouseDown);
            ThreeButton.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Three_MouseMove);
            ThreeButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Three_MouseUp);

            FourButton.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Four_MouseDown);
            FourButton.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Four_MouseMove);
            FourButton.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Four_MouseUp);

            clipRect.X = 0;
            clipRect.Y = 0;
            clipRect.Width = currentPictureBox.Image.Width;
            clipRect.Height = currentPictureBox.Image.Height;

            resetImageToPanel();

        }
        /************************窗口事件**************************/
        /**
         * 窗口变化时候
         */
        private void ImageEdit_ResizeBegin(object sender, EventArgs e)
        {
            resetImageToPanel();
        }
        /************************居中显示**************************/
        /**
         * 缩放图片到panel 居中
         */
        private static void resetImageToPanel()
        {
            int windowWidth = currentImageBox.Width;
            int windowHeight = currentImageBox.Height;

            int imageWidth = clipRect.Width;
            int imageHeight = clipRect.Height;

            if (imageWidth >= imageHeight)
            {
                if (imageWidth > windowWidth)
                {
                    double scaleHeight = (double)windowWidth / imageWidth * imageHeight;
                    currentPictureBox.Width = windowWidth;
                    currentPictureBox.Height = (int)scaleHeight;
                }
                else {
                    currentPictureBox.Width = (int)windowWidth;
                    currentPictureBox.Height = (int)windowHeight;
                }
            }
            else
            {
                if (imageHeight > windowHeight)
                {
                    double scaleWidth = (double)windowHeight / imageHeight * imageWidth;
                    currentPictureBox.Height = windowHeight;
                    currentPictureBox.Width = (int)scaleWidth;
                }
                else {
                    currentPictureBox.Width = (int)windowWidth;
                    currentPictureBox.Height = (int)windowHeight;
                }

            }

            int X = (windowWidth - currentPictureBox.Width) / 2;
            int Y = (windowHeight - currentPictureBox.Height) / 2;
            currentPictureBox.Location = new Point(X, Y);
        }
        /************************按钮事件**************************/
        // 复位
        private void reset_Click(object sender, EventArgs e)
        {
            rotaNum = 0;
            resetImageToPanel();
        }
        // 左旋
        private void roatleft_Click(object sender, EventArgs e)
        {
            currentPictureBox.Image = RotateImage(sourceImage, rotaNum -= 5);
        }
        // 右旋
        private void roatRight_Click(object sender, EventArgs e)
        {
            currentPictureBox.Image = RotateImage(sourceImage, rotaNum += 5);
        }
        // 旋转90度
        private void roat90_Click(object sender, EventArgs e)
        {
            currentPictureBox.Image = RotateImage(sourceImage, rotaNum -= 90);
        }
        // 旋转180度
        private void roat180_Click(object sender, EventArgs e)
        {
            currentPictureBox.Image = RotateImage(sourceImage, rotaNum -= 180);
        }
        // 水平镜像
        private void mirror_Click(object sender, EventArgs e)
        {
            //currentPictureBox.Image = RotateImage(sourceImage, rotaNum);
            currentPictureBox.Image = turnOverImage(currentPictureBox.Image, "mirror");
        }
        // 垂直镜像
        private void vertical_Click(object sender, EventArgs e)
        {
            //currentPictureBox.Image = RotateImage(sourceImage, rotaNum);
            currentPictureBox.Image = turnOverImage(currentPictureBox.Image, "vertical");
        }
        // 裁切
        private void clip_Click(object sender, EventArgs e)
        {
            clipMode = !clipMode;

            if (clipMode)
            {
                this.clip.BackColor = Color.Blue;
                this.clip.ForeColor = Color.White;
                this.beginPainting();

            }
            else 
            {
                this.clip.BackColor = Color.Transparent;
                this.clip.ForeColor = Color.Black;
                this.overPainting();
            }

        }
        /************************图像鼠标事件**************************/
        private void pictureBox_MouseWheel(object sender, MouseEventArgs e)
        {
            if (currentPictureBox.ClientRectangle.Contains(e.Location))
            {
                ((HandledMouseEventArgs)e).Handled = true;
                currentPictureBox.Focus();

                float zoomChange = e.Delta > 0 ? 2f : 0.5f;

                // Debug.WriteLine(e.Delta);

                // 计算缩放后图片的大小 
                int newWidth = (int)(currentPictureBox.Width * zoomChange);
                int newHeight = (int)(currentPictureBox.Height * zoomChange);

                int newX = 0;
                int newY = 0;

                if (e.Delta > 0)
                {
                    newX = (int)(currentPictureBox.Left - e.X);
                    newY = (int)(currentPictureBox.Top - e.Y);
                }
                else
                {
                    newX = (int)(currentPictureBox.Left + e.X / 2);
                    newY = (int)(currentPictureBox.Top + e.Y / 2);
                }

                currentPictureBox.Size = new Size(newWidth, newHeight);
                currentPictureBox.Location = new Point(newX, newY);

            }

        }
        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                isSelected = true;
            }
        }
        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (isSelected)//确定已经激发MouseDown事件,和鼠标在picturebox的范围内
            {
                currentPictureBox.Left = currentPictureBox.Left + (Cursor.Position.X - mouseDownPoint.X);
                currentPictureBox.Top = currentPictureBox.Top + (Cursor.Position.Y - mouseDownPoint.Y);
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                Cursor.Current = Cursors.SizeAll;
            }
            else
            {
                Cursor.Current = Cursors.Default;
            }
        }
        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            isSelected = false;
        }
        /*************************裁切平面鼠标事件*************************/
        private void clip_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                isClicked = true;
            }
        }
        private void clip_MouseMove(object sender, MouseEventArgs e)
        {
            if (isClicked)
            {
                int dotaX = mouseDownPoint.X - Cursor.Position.X;
                int dotaY = mouseDownPoint.Y - Cursor.Position.Y;

                currentClipPanel.Left = currentClipPanel.Left - dotaX;
                currentClipPanel.Top = currentClipPanel.Top - dotaY;

                // 刷新第一、二、三、四个点位置
                int newOneX = currentClipPanel.Location.X + currentClipPanel.Width / 2 - pointRadis / 2;
                int newTwoY = currentClipPanel.Location.Y + currentClipPanel.Height / 2 - pointRadis / 2;

                OneButton.Location = new Point(newOneX, currentClipPanel.Location.Y - pointRadis / 2);
                ThreeButton.Location = new Point(newOneX, currentClipPanel.Location.Y + currentClipPanel.Height - pointRadis / 2);

                TwoButton.Location = new Point(currentClipPanel.Location.X + currentClipPanel.Width - pointRadis / 2, newTwoY);
                FourButton.Location = new Point(currentClipPanel.Location.X - pointRadis / 2, newTwoY);

                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
            }
        }
        private void clip_MouseUp(object sender, MouseEventArgs e)
        {
            isClicked = false;
        }
        /*************************第一个点鼠标事件*************************/
        private void One_MouseDown(object sender, MouseEventArgs e) {
            Cursor.Current = Cursors.SizeNS;
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                isClickedOne = true;
            }
        }
        private void One_MouseMove(object sender, MouseEventArgs e)
        {
            if (isClickedOne) {
                Cursor.Current = Cursors.SizeNS;
                int dotaY = mouseDownPoint.Y - Cursor.Position.Y;

                if (ThreeButton.Location.Y - OneButton.Location.Y  > 50 || dotaY > 0) {

                    // 计算高度和位置
                    currentClipPanel.Height = currentClipPanel.Height + dotaY;
                    int newY = currentClipPanel.Location.Y - dotaY;
                    currentClipPanel.Location = new Point(currentClipPanel.Location.X, newY);
                    int newPointY = OneButton.Location.Y - dotaY;
                    OneButton.Location = new Point(OneButton.Location.X, newPointY);
                    // 刷新第二、四个点位置
                    int newTwoY = currentClipPanel.Location.Y + currentClipPanel.Height / 2 - pointRadis / 2;
                    TwoButton.Location = new Point(TwoButton.Location.X, newTwoY);
                    FourButton.Location = new Point(FourButton.Location.X, newTwoY);

                    mouseDownPoint.X = Cursor.Position.X;
                    mouseDownPoint.Y = Cursor.Position.Y;

                }
            }
        }
        private void One_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.Default;
            isClickedOne = false;
        }
        /*************************第二个点鼠标事件*************************/
        private void Two_MouseDown(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.SizeWE;
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                isClickedTwo = true;
            }

        }
        private void Two_MouseMove(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.SizeWE;

            if (isClickedTwo)
            {
                int dotaX = mouseDownPoint.X - Cursor.Position.X;
                if (TwoButton.Location.X - FourButton.Location.X > 50 || dotaX < 0) {
                    // 计算宽度和位置  
                    currentClipPanel.Width -= dotaX;

                    int newPointX = TwoButton.Location.X - dotaX;
                    TwoButton.Location = new Point(newPointX, TwoButton.Location.Y);
                    // 刷新第一、三个点位置
                    int newOneX = currentClipPanel.Location.X + currentClipPanel.Width / 2 - pointRadis / 2;
                    OneButton.Location = new Point(newOneX, OneButton.Location.Y);
                    ThreeButton.Location = new Point(newOneX, ThreeButton.Location.Y);

                    mouseDownPoint.X = Cursor.Position.X;
                    mouseDownPoint.Y = Cursor.Position.Y;
                }
            }
        }
        private void Two_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.Default;
            isClickedTwo = false;
        }
        /*************************第三个点鼠标事件*************************/
        private void Three_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                isClickedThree = true;
            }
        }
        private void Three_MouseMove(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.SizeNS;
            if (isClickedThree)
            {
                int dotaY = mouseDownPoint.Y - Cursor.Position.Y;
                if (ThreeButton.Location.Y - OneButton.Location.Y > 50 || dotaY < 0)
                {
                    // 计算高度和位置
                    currentClipPanel.Height = currentClipPanel.Height - dotaY;
                    int newPointY = ThreeButton.Location.Y - dotaY;
                    ThreeButton.Location = new Point(ThreeButton.Location.X, newPointY);
                    // 刷新第二、四个点位置
                    int newTwoY = currentClipPanel.Location.Y + currentClipPanel.Height / 2 - pointRadis / 2;
                    TwoButton.Location = new Point(TwoButton.Location.X, newTwoY);
                    FourButton.Location = new Point(FourButton.Location.X, newTwoY);

                    mouseDownPoint.X = Cursor.Position.X;
                    mouseDownPoint.Y = Cursor.Position.Y;
                }
            }
        }
        private void Three_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.Default;
            isClickedThree = false;
        }
        /*************************第四个点鼠标事件*************************/
        private void Four_MouseDown(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.SizeWE;
            if (e.Button == MouseButtons.Left)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                isClickedFour = true;
            }
        }
        private void Four_MouseMove(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.SizeWE;
            if (isClickedFour)
            {
                // 计算宽度和位置
                int dotaX = mouseDownPoint.X - Cursor.Position.X;
                if (TwoButton.Location.X - FourButton.Location.X > 50 || dotaX > 0)
                {
                    currentClipPanel.Width += dotaX;
                    int newX = currentClipPanel.Location.X - dotaX;
                    currentClipPanel.Location = new Point(newX, currentClipPanel.Location.Y);
                    int newPointX = FourButton.Location.X - dotaX;
                    FourButton.Location = new Point(newPointX, FourButton.Location.Y);
                    // 刷新第一、三个点位置
                    int newOneX = currentClipPanel.Location.X + currentClipPanel.Width / 2 - pointRadis / 2;
                    OneButton.Location = new Point(newOneX, OneButton.Location.Y);
                    ThreeButton.Location = new Point(newOneX, ThreeButton.Location.Y);

                    mouseDownPoint.X = Cursor.Position.X;
                    mouseDownPoint.Y = Cursor.Position.Y;
                }
            }
        }
        private void Four_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.Default;
            isClickedFour = false;
        }
        /***************************功能方法***********************/
        /**
         * 绘制裁切框
         */
        private void beginPainting()
        {
            Debug.WriteLine("====beginPainting====");
            OneButton.Visible = clipMode;
            TwoButton.Visible = clipMode;
            ThreeButton.Visible = clipMode;
            FourButton.Visible = clipMode;
            currentPictureBox.Image = RotateImage(sourceImage, rotaNum);
            currentPictureBox.Refresh();

            // 初始化位置
            setDefaultClipButtonPosition();
            currentClipPanel.Visible = clipMode;
        }
        /**
         * 结束绘制
         */
        private void overPainting()
        {
            Debug.WriteLine("====overPainting====");
            OneButton.Visible = clipMode;
            TwoButton.Visible = clipMode;
            ThreeButton.Visible = clipMode;
            FourButton.Visible = clipMode;
            currentPictureBox.Image = RotateImage(sourceImage, rotaNum);
            currentImageBox.Refresh();
           
            // 裁切
            clipBitmap();
            currentClipPanel.Visible = clipMode;
        }
        /**
         * 初始化裁切框调整按钮到图像尺寸
         */
        private static void setDefaultClipButtonPosition()
        {

            int halfButton = pointRadis / 2 ;
            // 设置拖拉按钮
            one.X = currentPictureBox.Location.X + currentPictureBox.Width / 2 - halfButton;
            one.Y = currentPictureBox.Location.Y - halfButton;
            OneButton.Location = one;

            two.X = currentPictureBox.Location.X + currentPictureBox.Width - halfButton;
            two.Y = currentPictureBox.Location.Y + currentPictureBox.Height / 2 - halfButton;
            TwoButton.Location = two;

            three.X = one.X;
            three.Y = currentPictureBox.Location.Y + currentPictureBox.Height - halfButton;
            ThreeButton.Location = three;

            four.X = currentPictureBox.Location.X - halfButton;
            four.Y = two.Y;
            FourButton.Location = four;

            currentClipPanel.Location = currentPictureBox.Location;
            currentClipPanel.Width = currentPictureBox.Width;
            currentClipPanel.Height = currentPictureBox.Height;

            Graphics graphicsClip = OneButton.CreateGraphics();
            graphicsClip.DrawRectangle(clipPen, clipRect);
            graphicsClip.Dispose();
        }
        /**
         * 裁切图片
         */
        private static void clipBitmap() {

            Image srcImage = currentPictureBox.Image;
            int X = currentClipPanel.Location.X - currentPictureBox.Location.X;
            int Y = currentClipPanel.Location.Y - currentPictureBox.Location.Y;
            X = X < 0 ? 0 : X * srcImage.Width / currentPictureBox.Width;
            Y = Y < 0 ? 0 : Y * srcImage.Height / currentPictureBox.Height;
            int Width = currentClipPanel.Width * srcImage.Width / currentPictureBox.Width;
            int Height = currentClipPanel.Height * srcImage.Height / currentPictureBox.Height;

            // 创建新图位图
            Bitmap bitmap = new Bitmap(Width, Height);
            bitmap.SetResolution(srcImage.HorizontalResolution, srcImage.VerticalResolution);
            // 创建作图区域
            Graphics graphic = Graphics.FromImage(bitmap);
            graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
            graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
            // 截取原图相应区域写入作图区
            Rectangle cRect = new Rectangle(X,Y, Width, Height);
            graphic.DrawImage(srcImage, 0, 0, cRect, GraphicsUnit.Pixel);
            graphic.Dispose();

            Debug.WriteLine("SourceWidth===========>" + sourceImage.Width);
            Debug.WriteLine("SourceHeight===========>" + sourceImage.Height);
            Debug.WriteLine("Width===========>" + bitmap.Width);
            Debug.WriteLine("Height===========>" + bitmap.Height);

            //从作图区生成新图
            // currentPictureBox.Image = Image.FromHbitmap( bitmap.GetHbitmap() );
            /********刷新图像*********/
            currentPictureBox.Image = bitmap;
            sourceImage = bitmap;
            rotaNum = 0;
            currentImageBox.Refresh();
            clipRect.X = 0;
            clipRect.Y = 0;
            clipRect.Width = Width;
            clipRect.Height = Height;
            /********刷新图像*********/
            resetImageToPanel();
        }
        /**
         * 旋转图像
         */
        private static Bitmap RotateImage(Image image, float angle)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }
            // 获取中心点  
            float halfWidth = image.Width / 2.0f;
            float halfHeight = image.Height / 2.0f;

            // 弧度转换
            angle = angle % 360;
            double radian = angle * Math.PI / 180.0;
            double cos = Math.Cos(radian);
            double sin = Math.Sin(radian);
            int width = image.Width;
            int height = image.Height;

            // 计算旋转后的图像容器长宽
            int resultWidth = (int)(Math.Max(Math.Abs(width * cos - height * sin), Math.Abs(width * cos + height * sin)));
            int resultHeight = (int)(Math.Max(Math.Abs(width * sin - height * cos), Math.Abs(width * sin + height * cos)));

            float centerX = resultWidth / 2;
            float centerY = resultHeight / 2;

            // 设置新的图像容器
            Bitmap newImage = new Bitmap(resultWidth, resultHeight);
            newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
            Graphics graphics = Graphics.FromImage(newImage);

            // 平移图像到中心点
            graphics.TranslateTransform(centerX, centerY);
            // 旋转
            graphics.RotateTransform(angle);
            // 再次平移回来
            graphics.TranslateTransform(-centerX, -centerY);

            // 将图片绘制到中心点上
            float resultX = centerX - halfWidth;
            float resultY = centerY - halfHeight;
            graphics.DrawImage(image, new PointF(resultX, resultY));
            graphics.Dispose();

            clipRect.X = 0;
            clipRect.Y = 0;
            clipRect.Width = resultWidth;
            clipRect.Height = resultHeight;

            resetImageToPanel();

            // 如果是裁切将显示裁切框
            /*if (clipMode)
            {
                Graphics graphicsClip = Graphics.FromImage(newImage);
                graphicsClip.DrawRectangle(rotaPen, clipRect);
                graphicsClip.Dispose();
            }*/

            /*Graphics graphicsClip = Graphics.FromImage(newImage);
            graphicsClip.DrawRectangle(rotaPen, clipRect);
            graphicsClip.Dispose();*/

            return newImage;
        }
        /**
         * 水平镜像
         */
        private static Image turnOverImage(Image image, string mode) {
            Graphics g = Graphics.FromImage(image);
            Rectangle rect = new Rectangle(0, 0, currentPictureBox.Image.Width, currentPictureBox.Image.Height);
            switch (mode) {
                case "mirror":
                    image.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    break;
                case "vertical":
                    image.RotateFlip(RotateFlipType.RotateNoneFlipY);
                    break;
            }
            g.DrawImage(image, rect);
            g.Dispose();
            return image;
        }
    }

}

目前只实现了这些,效率和内存方面还没有进行测试,计划添加文字标注和图片导出功能。

代码地址:https://github.com/suojianwen95/ImageEditer.git

标签:currentPictureBox,裁切,C#,System,Forms,Windows,图像处理,Location,new
From: https://www.cnblogs.com/suoyiling/p/18107875

相关文章

  • 模拟比赛-14届研究生组C++省赛
    A工作时长题意:若干条打卡记录字符串(年月日时分秒格式),保证打卡记录相邻。求该年工作时长。思路:对字符串处理,转换格式为秒数,排序后相邻相减求和。总结:2月有29天的情况要被4整除,如果能被100整除的话,一定要被400整除。structData{ intmonth;//5 intday;//8 inthour;//......
  • 抗噪/防干扰LCD显示液晶段码屏驱动VK2C23A/B适用于车载胎压仪表,三相电表,工业仪表,民生
    VK2C23A/B概述:      VK2C23A/B是一个点阵式存储映射的LCD驱动器,可支持最大224点(56SEGx4COM)或者最大416点(52SEGx8COM)的LCD屏。单片机可通过I2C接口配置显示参数和读写显示数据,也可通过指令进入省电模式。其高抗干扰,低功耗的特性适用于水电气表以及工控仪表类产品。特点:•......
  • Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field p
    完整日志:Causedby:java.lang.reflect.InaccessibleObjectException:Unabletomakefieldprivatefinaljava.lang.Classjava.lang.invoke.SerializedLambda.capturingClassaccessible:modulejava.basedoesnot"opensjava.lang.invoke"tounnamedmodule......
  • ActiViz中的读写类Reader/Writer
    文章目录前言一、vtkDataReader类1.vtkDataReader类的概述和基本用法2.不同数据格式的读取方法和示例二、vtkDataWriter类1.vtkDataWriter类的概述和基本用法2.不同数据格式的写入方法和示例三、vtkXMLReader类和vtkXMLWriter类1.vtkXMLReade......
  • Error in callback for immediate watcher “chartsData“: “Error: Initialize fail
     在使用echarts提示dom未找到,原因就是当我们封装了echarts组件初始化传值时通常会造成过早调用,也就是在数据还未处理完就已经调用init函数进行初始化,此时dom还未挂载成功,就会报这个错,这里解决可以使用nextTick()函数在初始化时延时调用;this.$nextTick(()=>{this.draw......
  • 当你遇到layer.alert is not a function怎么办
    下面我们来解决layer.alertisnotafunction的方法之一,下面来看一个GIS的例子,在登录之后,地图是加载出来的,当你点击区域定位是出现layer.alertisnotafunction。而我们的代码是没有bug,但是它还是报错。那是因为我们的url的地图出问题了,这是因为切图后的数据没有我们要的数......
  • C#中的MVVM
    MVVM(Model-View-ViewModel)是一种设计模式,通常与WPF(WindowsPresentationFoundation)和Xamarin等框架结合使用,用于构建基于XAML的应用程序。MVVM是MVC模式的衍生,旨在进一步分离应用程序的逻辑和界面。以下是MVVM的知识点以及可能会在面试中被问到的一些问题和答案:MVVM的......
  • C#中的微服务架构
    微服务架构是一种软件架构模式,通过将应用程序拆分成小型、独立的服务来实现。每个服务都运行在自己的进程中,并使用轻量级通信机制进行通信,例如HTTP接口或消息队列。以下是微服务架构的知识点以及可能会在面试中被问到的一些问题和答案:微服务架构的知识点:服务拆分:微服务架......
  • Qt/C++入门基础学习001-绘图基础
    这一节介绍Qt的绘图基础知识,我们都知道,Qt里绘图使用的是QPainter,但是首先需要弄明白:在什么上绘图和在哪里绘图,然后才是怎么绘图,我们就围绕这几个问题来展开。在什么上绘图TheQPaintDeviceclassisthebaseclassofobjectsthatcanbepaintedonwithQPainter.Apa......
  • Oracle 常用SQL笔记
    1.查询所有的分区表SELECT*FROMDBA_TAB_PARTITIONS; 2.创建分区altertable{TABLE_NAME}addpartitionSYS_P202403valueslessthan(TO_DATE('2024-03-0100:00:00','SYYYY-MM-DDHH24:MI:SS','NLS_CALENDAR=GREGORIAN')),partition......