UC_PicZoom.cs 10.9 KB
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace AutoCountMachine_Single
{

    public partial class UC_PicZoom : UserControl
    {
        Image img;
        Point mouseDown;
        int startx = 0;
        int starty = 0;
        int imgx = 0;
        int imgy = 0;

        bool mousepressed = false;
        float zoom = 1;
        float basezoom = 1;

        float dpiX = 0F;

        bool _TemplateMode=false;
        public bool TemplateMode
        {
            get
            {
                return _TemplateMode;
            }
            set
            {
                _TemplateMode = value;
                pictureBox.Refresh();
            }
        }
        public PictureBox GetPictureBox
        {
            get { return pictureBox; }
        }
        public UC_PicZoom()
        {

            InitializeComponent();
            //string imagefilename = @"d:\resout\Img20201021150145-Mark.png";
            //img = Image.FromFile(imagefilename);


            Graphics g = this.CreateGraphics();

            dpiX = g.DpiX;


            pictureBox.Paint += new PaintEventHandler(imageBox_Paint);
            pictureBox.MouseMove += pictureBox_MouseMove;
            pictureBox.MouseDown += imageBox_MouseDown;
            pictureBox.MouseUp += imageBox_MouseUp;
            pictureBox.MouseWheel += PictureBox_MouseWheel;
            pictureBox.MouseDoubleClick += PictureBox_MouseDoubleClick;

        }

        private void PictureBox_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (zoom / basezoom > 4F)
            {
                zoom = basezoom;
                doZoom(e.Location, false, 0F);
            }
            else
                doZoom(e.Location, true, 2.5F);
        }

        private void PictureBox_MouseWheel(object sender, MouseEventArgs e)
        {
            //OnMouseWheel(e);
        }
        int lockisa = 0;
        private void pictureBox_MouseMove(object sender, EventArgs e)
        {
            MouseEventArgs mouse = e as MouseEventArgs;
            bool inresize=false;
            int isa = 0;
            if (TemplateMode && lockisa>=0 &&   mouseontheline(mouse, out isa))
            {
                if (isa==1)
                {
                    pictureBox.Cursor = Cursors.SizeWE;
                }
                else if (isa == 2)
                {
                    pictureBox.Cursor = Cursors.SizeNS;
                }
                if (isa > 0) {
                    lockisa = isa;
                    inresize = true;
                }
            }
            else
            {
                pictureBox.Cursor = Cursors.Default;
            }

            if (mouse.Button == MouseButtons.Left)
            {
                if (TemplateMode && lockisa == 0) {
                    lockisa = isa;
                }

                if (lockisa<=0)
                {
                    lockisa = -1;
                    Point mousePosNow = mouse.Location;

                    int deltaX = mousePosNow.X - mouseDown.X;
                    int deltaY = mousePosNow.Y - mouseDown.Y;

                    imgx = (int)(startx + (deltaX / zoom));
                    imgy = (int)(starty + (deltaY / zoom));


                }
                else if (lockisa>0)
                {
                    //rect.Width = (int)(mouse.X * zoom);
                    //rect.Height = (int)(mouse.Y * zoom);
                    if (lockisa==1)
                        rect.Width = mouse.X - rect.X;
                    else if (lockisa == 2)
                        rect.Height = mouse.Y - rect.Y;

                    if (rect.Width < 10)
                        rect.Width = 10;
                    if (rect.Height < 10)
                        rect.Height = 10;

                }
                pictureBox.Refresh();
            }
            else {
                lockisa = 0;
            }
            //Console.WriteLine($"x:{mouse.X},y:{mouse.Y}");
            //Console.WriteLine($"imgx:{imgx},imgy:{imgx}");

            
        }
        bool mouseontheline(MouseEventArgs mouse, out int isa) {
            isa = 0;
            int offset = 6;
            if (mouse.X > rect.X+rect.Width - offset && mouse.X < rect.X + rect.Width + offset && mouse.Y> rect.Y && mouse.Y< rect.Y+rect.Height)
            {
                isa = 1;
                return true;
            }

            if (mouse.Y > rect.Y + rect.Height - offset && mouse.Y < rect.Y + rect.Height + offset && mouse.X > rect.X && mouse.X < rect.X + rect.Width)
            {
                isa = 2;
                return true;
            }

            return false;
        }

        private void imageBox_MouseDown(object sender, EventArgs e)
        {
            MouseEventArgs mouse = e as MouseEventArgs;

            if (mouse.Button == MouseButtons.Left)
            {
                if (!mousepressed)
                {
                    mousepressed = true;
                    mouseDown = mouse.Location;
                    startx = imgx;
                    starty = imgy;
                }
            }
        }

        private void imageBox_MouseUp(object sender, EventArgs e)
        {
            mousepressed = false;
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            MouseEventArgs mouse = e as MouseEventArgs;

            if (e.Delta > 0)
            {
                doZoom(mouse.Location, true);
            }
            else if (e.Delta < 0)
            {
                doZoom(mouse.Location, false);
            }
        }

        void doZoom(Point mousePoint, bool isZoomin, float zoonRate = 0.2F)
        {
            float oldzoom = zoom;

            if (isZoomin)
            {
                //zoom += 0.1F;
                zoom = zoom * (1F + zoonRate);
            }

            else
            {
                //zoom = Math.Max(zoom - 0.1F, basezoon);
                zoom = Math.Max(zoom * (1F - zoonRate), basezoom);
            }
            if (_TemplateMode && zoom>4) {
                zoom = 4;
            }
            Console.WriteLine(zoom);
            Point mousePosNow = mousePoint;
            //点击坐标
            int x = mousePosNow.X - pictureBox.Location.X;
            int y = mousePosNow.Y - pictureBox.Location.Y;
            //对应现在的图像坐标
            int oldimagex = (int)(x / oldzoom);
            int oldimagey = (int)(y / oldzoom);
            //对应放大后的图像坐标
            int newimagex = (int)(x / zoom);
            int newimagey = (int)(y / zoom);

            imgx = newimagex - oldimagex + imgx;
            imgy = newimagey - oldimagey + imgy;

            pictureBox.Refresh();

        }
        public Rectangle GetRectangle
        {
            get {
                return new Rectangle((int)(imgx * -1 + rect.X / zoom), (int)(imgy * -1 + rect.Y / zoom), (int)(rect.Width / zoom), (int)(rect.Height / zoom));
            }
        }
        Rectangle rect = new Rectangle(150, 150, 150, 150);
        private void imageBox_Paint(object sender, PaintEventArgs e)
        {
            if (img == null)
                return;
            if (zoom == basezoom)
            {
                imgx = 0;
                imgy = 0;
            }
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            e.Graphics.ScaleTransform(zoom, zoom);
            e.Graphics.DrawImage(img, imgx, imgy);
            if (TemplateMode)
            {
                Brush brush = new SolidBrush(Color.Red);
                Pen pen = new Pen(brush, 1f / zoom);
                e.Graphics.DrawRectangle(pen, new Rectangle((int)(rect.X / zoom), (int)(rect.Y / zoom), (int)(rect.Width / zoom), (int)(rect.Height / zoom)));
                Console.WriteLine("rect.Width / zoom=" + rect.Width / zoom);
            }
        }

        public void rectAdd(int width, int height) {
            rect.Width += (int)(width * zoom);
            rect.Height += (int)(height * zoom);
            pictureBox.Refresh();
        }
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            const int WM_KEYDOWN = 0x100;
            const int WM_SYSKEYDOWN = 0x104;

            if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
            {
                switch (keyData)
                {
                    case Keys.Right:
                        imgx -= (int)(pictureBox.Width * 0.1F / zoom);
                        pictureBox.Refresh();
                        break;

                    case Keys.Left:
                        imgx += (int)(pictureBox.Width * 0.1F / zoom);
                        pictureBox.Refresh();
                        break;

                    case Keys.Down:
                        imgy -= (int)(pictureBox.Height * 0.1F / zoom);
                        pictureBox.Refresh();
                        break;

                    case Keys.Up:
                        imgy += (int)(pictureBox.Height * 0.1F / zoom);
                        pictureBox.Refresh();
                        break;

                    case Keys.PageDown:
                        imgy -= (int)(pictureBox.Height * 0.90F / zoom);
                        pictureBox.Refresh();
                        break;

                    case Keys.PageUp:
                        imgy += (int)(pictureBox.Height * 0.90F / zoom);
                        pictureBox.Refresh();
                        break;
                }
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        public Image Image {
            set {
                if (img != null)
                    img.Dispose();
                img = value;
                if (value == null) {
                    pictureBox.Enabled = false;
                    return;
                }
                pictureBox.Enabled = true;
                zoom = ((float)pictureBox.Width / (float)img.Width) * (img.HorizontalResolution / dpiX);
                basezoom = zoom;

                if (pictureBox.Height > pictureBox.Width)
                {
                    
                    zoom = ((float)pictureBox.Width / (float)img.Width) * (img.HorizontalResolution / dpiX);
                    imgy = (int)((img.Height - pictureBox.Height) * zoom / -2);
                }
                else
                {                    
                    zoom = ((float)pictureBox.Height / (float)img.Height) * (img.VerticalResolution / dpiX);
                    imgx = (int)((img.Width - pictureBox.Width)*zoom / -2);
                }

                rect.X = (int)((img.Width / 2 - 500 / 2)*zoom);
                rect.Y = (int)((img.Height / 4 - 400 / 2)* zoom);
                rect.Width = (int)(500 * zoom);
                rect.Height = (int)(400 * zoom);

                pictureBox.Refresh();
            }
        }

    }
}