通过将光标悬停在另一个图片框中显示放大的部分图片框c#

发布于 2025-01-11 13:36:35 字数 619 浏览 3 评论 0原文

我正在开发一个在 pictureBox 中显示来自尼康相机的实时图像的程序。我希望能够将光标悬停在图像上,并在另一个图片框中显示光标周围的放大区域。我还想添加十字准线而不是鼠标指针。到目前为止,我找到的唯一解决方案如下:

缩放光标后面的第二个图片框中的图像

它完全符合我的要求,但是我无法让它工作。更具体地说,picZoom 中没有显示任何内容。在示例中,加载图像,而在我的例子中,显示视频流。这可能就是我无法让它发挥作用的原因。我对 C# 比较陌生,并没有完全理解这个例子。

假设我有 picBox,可以在其中接收视频流。如何在 picZoom 中用十字准线显示光标周围 picBox 的一部分(假设尺寸为 x,y 的光标周围的矩形),如示例中所示。我不需要担心 picBox 和 picZoom 的不同尺寸,因为它们不会变化。我还希望能够通过因子 ZoomFactor 来改变缩放程度。

如果有人能给我指点或解决方案,我将不胜感激。另外,如果我的问题格式不正确,我很抱歉,我是论坛的新手。

谢谢你!

亚历山大

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑红尘 2025-01-18 13:36:36

我会这样处理它

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

要连接它,您所要做的就是在表单中添加一个放大镜,给它一个大小,然后将其源设置为>PictureBox 你希望它放大。

   this.magnifier1.Source = this.pictureBox1;

我使用此答案中的方法来忽略放大镜窗口中的消息。

重要的是,我只为源 PictureBox 的 PictureBoxSizeMode.Normal SizeMode 编写了缩放数学。但我认为这是一个很好的开始。

不能 100% 确定您想要什么十字准线,但这使用内置的十字准线光标。

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.

祁梦 2025-01-18 13:36:36

通过一些调整,您可以将 @Wyck 的代码与 PictureBoxSizeMode.StretchImage 一起使用

protected override void OnPaint(PaintEventArgs pe)
    {
        if (!DesignMode && Source != null && Source.Image != null)
        {
            Rectangle destRect = new (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:
            float stretch_X = source.Image.Width  / (float)source.Width;
            float stretch_Y = source.Image.Height / (float)source.Height;
            Rectangle srcRect = new ((int)(sourcePoint.X * stretch_X) - Width / 4, (int)(sourcePoint.Y * stretch_Y) - Height / 4, Width / 2, Height / 2);
            pe.Graphics.DrawImage(source.Image, destRect, srcRect, GraphicsUnit.Pixel);
        }
        else
        {
            base.OnPaint(pe);
        }
    }

With some adjust, you can use @Wyck 's code with PictureBoxSizeMode.StretchImage

protected override void OnPaint(PaintEventArgs pe)
    {
        if (!DesignMode && Source != null && Source.Image != null)
        {
            Rectangle destRect = new (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:
            float stretch_X = source.Image.Width  / (float)source.Width;
            float stretch_Y = source.Image.Height / (float)source.Height;
            Rectangle srcRect = new ((int)(sourcePoint.X * stretch_X) - Width / 4, (int)(sourcePoint.Y * stretch_Y) - Height / 4, Width / 2, Height / 2);
            pe.Graphics.DrawImage(source.Image, destRect, srcRect, GraphicsUnit.Pixel);
        }
        else
        {
            base.OnPaint(pe);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文