Home > Net >  Display zoomed in part of pictureBox in another pictureBox by hovering cursor c#
Display zoomed in part of pictureBox in another pictureBox by hovering cursor c#

Time:03-04

I am working on a program that displays the liveView image from a Nikon camera in a pictureBox. I want to be able to hover with the cursor over the image and display a zoomed in area around the cursor in another picturebox. I would also like to add a crosshair instead of mouse pointer. The only solution I have found so far is the following:

zoom an image in a second picturebox following cursor

It does exactly what I want, however I can not get it to work. More specifically, nothing is showing up in picZoom. In the example, images are loaded while in my case, a video stream is shown. That might be the reason why I am not getting it to work. I am relatively new to c#, and did not fully understand the example.

Lets say I have picBox where I receive the video stream. How do I show a portion of picBox around the cursor (let's say a rectangle around the cursor of dimensions x,y) in picZoom with a crosshair as in the example. I do not need to worry about differing dimensions of picBox and picZoom since they will not vary. I also want to be able to vary the degree of zoom by a factor zoomFactor.

If anyone could give me pointers or a solution, it would be greatly appreciated. Also, sorry if my question is poorly formatted, I am new to the forum.

Thank you!

Alexander

CodePudding user response:

I would approach it like this

using System;
using System.Drawing;
using System.Windows.Forms;

namespace MagnifierExample
{
    class Magnifier : PictureBox
    {
        public Magnifier()
        {
            Visible = false;
        }

        PictureBox source;
        private Point sourcePoint;
        Cursor oldCursor;

        public PictureBox Source
        {
            get
            {
                return source;
            }
            set
            {
                if (source != null)
                {
                    source.MouseEnter -= Source_MouseEnter;
                    source.MouseLeave -= Source_MouseLeave;
                    source.MouseMove -= Source_MouseMove;
                    source.Cursor = oldCursor;
                }
                source = value;
                if (source != null)
                {
                    source.MouseEnter  = Source_MouseEnter;
                    source.MouseLeave  = Source_MouseLeave;
                    source.MouseMove  = Source_MouseMove;
                    oldCursor = source.Cursor;
                    source.Cursor = Cursors.Cross;
                }
            }
        }

        private void Source_MouseEnter(object sender, EventArgs e)
        {
            Visible = true;
            BringToFront();
        }

        private void Source_MouseLeave(object sender, EventArgs e)
        {
            Visible = false;
        }

        private void Source_MouseMove(object sender, MouseEventArgs e)
        {
            sourcePoint = e.Location;
            Location = new Point(source.Location.X   e.X - Width / 2, source.Location.Y   e.Y - Height / 2);
            Invalidate();
        }

        protected override void WndProc(ref Message m)
        {
            const int WM_NCHITTEST = 0x0084;
            const int HTTRANSPARENT = (-1);

            if (!DesignMode && m.Msg == WM_NCHITTEST)
            {
                m.Result = (IntPtr)HTTRANSPARENT;
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            if (!DesignMode && Source != null && Source.Image != null)
            {
                Rectangle destRect = new Rectangle(0, 0, Width, Height);
                // IMPORTANT: This calculation will depend on the SizeMode of the source and the amount you want to zoom.
                // This does 2x zoom and works with PictureBoxSizeMode.Normal:
                Rectangle srcRect = new Rectangle(sourcePoint.X - Width / 4, sourcePoint.Y - Height / 4, Width / 2, Height / 2);
                pe.Graphics.DrawImage(Source.Image, destRect, srcRect, GraphicsUnit.Pixel);
            }
            else
            {
                base.OnPaint(pe);
            }
        }
    }
}

To hook it up all you have to do is add a Magnifier to your form, give it a size, and set its Source to the PictureBox you want it to magnify.

   this.magnifier1.Source = this.pictureBox1;

I used the approach in this answer to ignore messages from the magnifier window.

Importantly, I only coded up the zoom math for the PictureBoxSizeMode.Normal SizeMode of the source PictureBox. But I think this is a pretty good start.

Not 100% sure what you wanted for crosshairs, but this uses the built-in crosshair cursor.

CodePudding user response:

thank you very much for your detailed answer. I am sure that the code works great, but I must admit that I am very new to c#, so I do not really understand how to use it. For example, I do not know what you mean by "add a Magnifier to my form" or even how to use this code. Is there a more simplified way of doing this, or could you give me a description on how to use it?

Sorry for the trouble, I have barely scratched the surface of c# programming.

Alexander

  • Related