【问题标题】:The image is supposed to be moved inside the PictureBox via MouseMove events图像应该通过 MouseMove 事件在 PictureBox 内移动
【发布时间】:2021-04-22 17:45:37
【问题描述】:

在开始一个项目之前,我想事先知道以下是否可行。
应用程序创建一个System.Drawing.Bitmap 并在其上绘画。

Bitmap 比 PictureBox 大得多。 Bitmap 和 PictureBox 的高度是一样的。现在我希望能够通过按下鼠标左键并在 PictureBox 内(沿)移动它来将图像从左向右移动。

看图:

【问题讨论】:

  • 一个 PBox.Image 是固定的。一个常见且简单的解决方案将 PBox 嵌套在 Panel 中,并将整个 PBox 移动到 Panel 中。
  • Zoom and translate an Image from the mouse location:跟随动画到结束,然后检查代码。顺便说一句,您在那里缺少一些抗锯齿功能。
  • 非常感谢你们两位。 @Jimi 从“PictureBox”继承并开发自己的东西的好主意。效果很好! ??????
  • 这只是为了简化鼠标交互。该代码背后的idea 是仅处理位图descriptor,即定义位图边界的 RectangleF,仅考虑最后一刻应用的效果的总和。这样,您只需要处理图像的 shape,而不是其内容。 -- 动画中的图像几乎是 4K 大小:使用这种方法,您可以处理它,因为它是一个小得多的对象,所以它变得非常快,即使您应用了很多效果/变换。
  • 我现在已经从代码中读出了这一点。我注释掉了我不需要的东西(例如缩放);我用new PointF(imageLocation.X + (e.Location.X - mouseLocation.X), imageLocation.Y+ (e.Location.Y - mouseLocation.Y)); 制作了new PointF(imageLocation.X + (e.Location.X - mouseLocation.X), imageLocation.Y);,因为我不想在高度上移动。 ??????

标签: c# winforms picturebox mousemove


【解决方案1】:

我刚刚意识到我还没有回答,我正在努力弥补。 作为解决方案,我使用 Jimi 的解决方案。我已经缩短了这里的代码以满足我的需要。

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;

namespace Zoom_an_image_from_the_mouse_location
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
            string imagePath = "C:\\Users\\yourPath\\Pictures\\....jpeg";
            drawingImage = (Bitmap)Image.FromStream(new MemoryStream(File.ReadAllBytes(imagePath)));
            imageRect = new RectangleF(Point.Empty, drawingImage.Size);

            canvas = new PictureBoxEx(new Size(525,700));
            canvas.Location = new Point(10, 10);
            canvas.MouseMove += this.canvas_MouseMove;
            canvas.MouseDown += this.canvas_MouseDown;
            canvas.MouseUp += this.canvas_MouseUp;
            canvas.Paint += this.canvas_Paint;
            this.Controls.Add(canvas);
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            this.BackColor = Color.FromArgb(174, 184, 177);
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
        }

        private float rotationAngle = 0.0f;
        private float zoomFactor = 1.0f;

        private RectangleF imageRect = RectangleF.Empty;
        private PointF imageLocation = PointF.Empty;
        private PointF mouseLocation = PointF.Empty;

        private Bitmap drawingImage = null;
        private PictureBoxEx canvas = null;

        private void canvas_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            mouseLocation = e.Location;
            imageLocation = imageRect.Location;
            canvas.Cursor = Cursors.NoMove2D;
        }

        private void canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            imageRect.Location =
                new PointF(imageLocation.X + (e.Location.X - mouseLocation.X),
                           imageLocation.Y); //+ (e.Location.Y - mouseLocation.Y));
            canvas.Invalidate();
        }

        private void canvas_MouseUp(object sender, MouseEventArgs e) =>
            canvas.Cursor = Cursors.Default;

        private void canvas_Paint(object sender, PaintEventArgs e)
        {
            var drawingRect = GetDrawingImageRect(imageRect);

            using (var mxRotation = new Matrix())
            using (var mxTransform = new Matrix())
            {

                e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;

                mxRotation.RotateAt(rotationAngle, GetDrawingImageCenterPoint(drawingRect));
                mxTransform.Multiply(mxRotation);

                e.Graphics.Transform = mxTransform;
                e.Graphics.DrawImage(drawingImage, drawingRect);
            }
        }


        #region Drawing Methods

        public RectangleF GetScaledRect(RectangleF rect, float scaleFactor) =>
            new RectangleF(rect.Location,
            new SizeF(rect.Width * scaleFactor, rect.Height * scaleFactor));

        public RectangleF GetDrawingImageRect(RectangleF rect) =>
            GetScaledRect(rect, zoomFactor);

        public PointF GetDrawingImageCenterPoint(RectangleF rect) =>
            new PointF(rect.X + rect.Width / 2f, rect.Y + rect.Height / 2f);

        #endregion
    }
}

[DesignerCategory("Code")]
public class PictureBoxEx : PictureBox
{
    public PictureBoxEx() : this(new Size(525, 700)) { }
    public PictureBoxEx(Size size)
    {
        SetStyle(ControlStyles.Selectable | ControlStyles.UserMouse, true);
        this.BorderStyle = BorderStyle.FixedSingle;
        this.Size = size;
    }
}

【讨论】:

    猜你喜欢
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2014-06-16
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多