Quantcast
Channel: Programming Forums
Viewing all articles
Browse latest Browse all 51036

Zooming an image centered on mouse coordinates

$
0
0
Hello,

I've been trying to solve this for a couple of days now but i just don't get it..

I have a UserControl which acts like an advanced version of the PictureBox. Changing image / panning the image is not problem nor is Zooming really.

The problem I'm having is related to the zooming in/out. When I scroll the mouse-wheel on the image, the image zooms in/out like it should, however, it ignores where the mouse cursor is places, just zooms in on the last know position set by panning the image.. What i want is: A way for the image to zoom in/out based on the mouse coordinates. Like, if i place the mouse at 400, 400 on the image and zoom in, i want the cursor to zoom in on that area (and keep the mouse over 400, 400) Kinda like how Google Maps zooming works.

Here's my UserControl so far:

public partial class ZoomablePanel : UserControl
    {
        [Description("Pan button"), Category("Data"), DefaultValue(MouseButtons.Right), Browsable(true)]
        public MouseButtons Pan
        {
            get { return this.PanButton; }
            set { this.PanButton = value; }
        }

        [Description("Current Zoom Factor"), Category("Data"), DefaultValue(1), Browsable(true)]
        public Double Zoom
        {
            get { return this.ZoomFactor; }
            set { this.ZoomFactor = value; }
        }

        [Description("The Image"), Category("Data"), DefaultValue(null), EditorBrowsable(EditorBrowsableState.Always), Browsable(true)]
        public Image BGImage
        {
            get { return this.initialImage; }
            set { this.initialImage = value; }
        }

        public PointF Origin;
        private MouseButtons PanButton = System.Windows.Forms.MouseButtons.Right;

        [DefaultValue(1)]
        private Double ZoomFactor;

        private Image initialImage;

        private PointF Start;

        private RectangleF DestRect, SrcRect;

        public MapPanel()
        {
            if (this.Origin == null)
                this.Origin = new PointF(0, 0);
            this.Start = this.Origin;

            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }

        protected override void onmousewheel(MouseEventArgs e)
        {
            base.onmousewheel(e);

            int Delta = (e.Delta / 120);

            double prevZoom = this.ZoomFactor;

            this.ZoomFactor = this.ZoomFactor + (Delta * 0.5);

            if (this.ZoomFactor > 5) this.ZoomFactor = 5;
            if (this.ZoomFactor < 0.5) this.ZoomFactor = 0.5;

            if (prevZoom != this.ZoomFactor)
            {

                this.Origin.X = e.X;
                this.Origin.Y = e.Y;

                if (this.Origin.X > initialImage.Width - (ClientSize.Width / this.ZoomFactor))
                    this.Origin.X = initialImage.Width - (float)(ClientSize.Width / this.ZoomFactor);
                if (this.Origin.Y > initialImage.Height - (ClientSize.Height / this.ZoomFactor))
                    this.Origin.Y = initialImage.Height - (float)(ClientSize.Height / this.ZoomFactor);
                if (this.Origin.X < 0) this.Origin.X = 0;
                if (this.Origin.Y < 0) this.Origin.Y = 0;

                this.Invalidate();
            }
        }

        protected override void onmousedown(MouseEventArgs e)
        {
            base.onmousedown(e);

            if (e.Button == this.PanButton)
            {
                this.Start.X = e.X;
                this.Start.Y = e.Y;
            }
        }

        protected override void onmousemove(MouseEventArgs e)
        {
            if (e.Button == this.PanButton)
            {
                float DeltaX = this.Start.X - e.X;
                float DeltaY = this.Start.Y - e.Y;

                this.Origin.X = this.Origin.X + (float)(DeltaX / this.ZoomFactor);
                this.Origin.Y = this.Origin.Y + (float)(DeltaY / this.ZoomFactor);

                if (this.Origin.X < 0) this.Origin.X = 0;
                if (this.Origin.Y < 0) this.Origin.Y = 0;

                if (this.Origin.X > initialImage.Width - (ClientSize.Width / this.ZoomFactor))
                    this.Origin.X = initialImage.Width - (float)(ClientSize.Width / this.ZoomFactor);
                if (this.Origin.Y > initialImage.Height - (ClientSize.Height / this.ZoomFactor))
                    this.Origin.Y = initialImage.Height - (float)(ClientSize.Height / this.ZoomFactor);

                if (this.Origin.X < 0) this.Origin.X = 0;
                if (this.Origin.Y < 0) this.Origin.Y = 0;

                this.Start.X = e.X;
                this.Start.Y = e.Y;

                this.Invalidate();
            }
            base.onmousemove(e);
        }


        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            DestRect = new RectangleF(0, 0, ClientSize.Width, ClientSize.Height);

            if (initialImage != null && this.Origin != null && this.ZoomFactor > 0)
            {
                if (this.Origin.X > initialImage.Width - (ClientSize.Width / this.ZoomFactor))
                    this.Origin.X = initialImage.Width - (float)(ClientSize.Width / this.ZoomFactor);
                if (this.Origin.Y > initialImage.Height - (ClientSize.Height / this.ZoomFactor))
                    this.Origin.Y = initialImage.Height - (float)(ClientSize.Height / this.ZoomFactor);
                if (this.Origin.X < 0) this.Origin.X = 0;
                if (this.Origin.Y < 0) this.Origin.Y = 0;
                this.Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.Clear(this.BackColor);
            Graphics g = e.Graphics;
            DrawImage(ref g);
        }

        private void DrawImage(ref Graphics g)
        {
            if (initialImage == null) return;
            SrcRect = new RectangleF(Origin.X, Origin.Y, (float)(ClientSize.Width / ZoomFactor), (float)(ClientSize.Height / ZoomFactor));
            g.DrawImage(initialImage, DestRect, SrcRect, GraphicsUnit.Pixel);
        }

    }



Viewing all articles
Browse latest Browse all 51036

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>