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

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

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

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

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

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

谢谢!

亚历山大

我会这样处理

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

要连接它,您所要做的就是在表单中添加一个 Magnifier,给它一个大小,然后将其 Source 设置为您想要的 PictureBox放大。

   this.magnifier1.Source = this.pictureBox1;

我使用 this answer 中的方法来忽略来自放大镜 window 的消息。

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

不是 100% 确定您想要什么十字准线,但这使用 built-in 十字准线光标。