C# 获取缩放图片上的鼠标位置

C# 获取缩放图片上的鼠标位置,c#,bitmap,position,mouse,picturebox,C#,Bitmap,Position,Mouse,Picturebox,我正在创建一个截图制作/上传程序,一切都很好,但现在我想整合一些东西,比如绘画。首先我要创建铅笔函数。但问题开始了,我可以画:D,但不是在我的鼠标位置上。他采取了其他的立场,然后我的光标 因此,问题是: 如何在缩放的图片盒上获取鼠标位置 我的代码: private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (draw && pencil) {

我正在创建一个截图制作/上传程序,一切都很好,但现在我想整合一些东西,比如绘画。首先我要创建铅笔函数。但问题开始了,我可以画:D,但不是在我的鼠标位置上。他采取了其他的立场,然后我的光标

因此,问题是: 如何在缩放的图片盒上获取鼠标位置

我的代码:

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (draw && pencil)
        {
            Graphics panel = Graphics.FromImage(ScreenShot);

            Pen pen = new Pen(Color.Black, 14);

            pen.EndCap = LineCap.Round;
            pen.StartCap = LineCap.Round;

            panel.DrawLine(pen, pX, pY, e.X, e.Y);

            pictureBox1.CreateGraphics().DrawImage(ScreenShot, pictureBox1.Width, pictureBox1.Height);

            pictureBox1.Invalidate();
        }
        Point p = pictureBox1.PointToClient(Cursor.Position);

        pX = p.X;
        pY = p.Y;
    }

在缩放图像上使用鼠标时,报告的像素是缩放的坐标。所以我们需要得到真正的像素

在不知何故安排好事情之后

float pbZoom = 3f;  // the factor by which the PictureBox is zoomed in or out

pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox.ClientSize = new Size((int)(pictureBox.Image.Width * pbZoom),
         (int)(pictureBox.Image.Height * pbZoom));

pictureBox.Paint     += pictureBox_Paint;
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseMove += pictureBox_MouseMove;
pictureBox.MouseUp   += pictureBox_MouseUp;
。。您可以将要绘制的事件写入缩放图像中

首先使用辅助函数撤消点的缩放:

PointF unZoomed(PointF pt) { return new PointF(pt.X / pbZoom, pt.Y / pbZoom );}
为了简单起见,让我们在类级别保留一些内容:

PointF mDown    = PointF.Empty;   // mouse down point
PointF mCurrent = PointF.Empty;   // current mouse location
我们通过计算未缩放的
e.Location
来启动每个鼠标事件

我们的测试在表面上画了一条直线,移动的红线,直到你释放鼠标。然后,该线以绿色绘制到图像中

MouseDown
仅存储未缩放的起点:

void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
    mDown = unZoomed(e.Location);
}
MouseMove
中,我们存储当前点并触发绘制事件:

void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.None) return;

    PointF e_ = unZoomed(e.Location);
    mCurrent = e_;
    pictureBox.Invalidate();
}
MouseUp
中,我们将线绘制到
PictureBox
Image
中,改变其像素;然后我们设置
图像
并重置点:

void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
    Bitmap bmp = (Bitmap) pictureBox.Image;
    using (Graphics G = Graphics.FromImage(bmp))
    {
        G.SmoothingMode = SmoothingMode.HighQuality;
        G.DrawLine(Pens.Green, mDown, mCurrent);
     }
    mDown = PointF.Empty;
    mCurrent = PointF.Empty;
    pictureBox.Image = bmp;

}
要在控件曲面上绘制,我们使用
Paint
事件。要绘制比例,我们使用
矩阵

void pictureBox_Paint(object sender, PaintEventArgs e)
{
    Matrix scaleMatrix = new Matrix();
    scaleMatrix.Scale(pbZoom, pbZoom);
    e.Graphics.MultiplyTransform(scaleMatrix);
    e.Graphics.DrawLine(Pens.Red, mDown, mCurrent);
}

我还使用缩放图像。我只是简单地使用这个代码,它正在工作。所以,在放大/缩小之前,您可以与位图(原始图像)进行比较

private void pbInput_MouseMove(object sender, MouseEventArgs e) { 
    if (pbInput.Image == null) {
        mouseY.Text = "";
        mouseX.Text = "";
    }

    else {
        Bitmap b = new Bitmap(pbInput.Image);
        int x = b.Width * e.X / pbInput.Width;
        int y = b.Height * e.Y / pbInput.Height;

        mouseX.Text = x.ToString();
        mouseY.Text = y.ToString();
    }
}

您需要做(至少)两件事中的一件:a)计算从缩放世界到未缩放世界的点和/或b)通过缩放图形对象以缩放模式绘制。如果你学习,你可以在工作中看到两者对于a)您还需要缩放笔的宽度!(尽可能对所有数字使用浮点!!)。顺便说一句:不需要使用PointToClient-使用e.Location等参数,并将它们除以缩放因子!不要在MouseMove中画画,而是在Paint事件中画画。在MouseMove中,存储绘制事件中绘制的点等的坐标。在知道自己在做什么之前不要创建图形对象,使用Paint e.Graphics param中的图形对象,不要命名图形对象面板,这会让每个人都感到困惑,最有可能的是从自己收集点开始,然后立即在scalePoint函数中转换它们,这并不是什么额外的工作。在GDI+中进入图形模型确实有一定的学习曲线,但实际上不需要担心任何事情..谢谢奇怪的问题,但你可能有skype吗。这就是我正在做的:我正忙于另一个更新您解决了问题了吗?