2014-10-20 18 views
0

我目前有一个图片框,用户将在图片框中点击并拖动以在图像上绘制矩形(可以定期更改)。当它们完成时(mouse_up),我将在文本框中显示矩形的相对点到分辨率。在picturebox中绘制矩形对于鼠标没有做到正确的比例

因此,例如,用户从左上角(0,0)到1920 x 680图像(picturebox.right,picturebox.bottom)的右下方画一个矩形,文本框将显示(1920, 680)作为终点。这主要是比例的东西。

我使用前一个问题的回答(Having trouble drawing simple rectangle in picturebox)中的代码来绘制它。

问题:由于图像必须在拉伸模式下完成,因此该框不遵循鼠标。它们通常很大(如1920 x 680),不适合常规GUI。有多种解决方案,因此必须随比例动态变化。如果不进行编辑,这段代码在正常模式下效果很好,但这对于可用性不起作用。所以,当你绘制盒子时,它非常小,而不是相对于鼠标(所以我不能在文本框上显示结束点)。

下面是我的意思的例子。我拖着我的鼠标横跨半个图像: enter image description here

我已经试过:我试图以对抗比它表演,但它仍然不能解决显示终点问题,或者它真的跟着鼠标那么好。它的左边通常至少有十个左右的像素。这是我对于调整代码:

Private Sub DrawRectangle(ByVal pnt As Point) 

    Try 
     Dim g As Graphics 

     g = Graphics.FromImage(img) 

     g.DrawImage(imgClone, 0, 0) 'we are clearing img with imgClone. imgClone contains the original image without the rectangles 

     Dim w_ratio As Integer = Math.Floor(img.Width/pbZoneImage.Width) 
     Dim h_ratio As Integer = Math.Floor(img.Height/pbZoneImage.Height) 
     Dim customPen As New Pen(currentColor, 5) 

     'If pnt.X = mouse_Down.X Or pnt.Y = mouse_Down.Y Then 
     ' g.DrawLine(customPen, mouse_Down.X, mouse_Down.Y, pnt.X * w_ratio, pnt.Y * h_ratio) 

     'Else 
     theRectangle = New Rectangle(Math.Min(mouse_Down.X, pnt.X * w_ratio), Math.Min(mouse_Down.Y, pnt.Y * h_ratio), 
        Math.Abs(mouse_Down.X - pnt.X * w_ratio), Math.Abs(mouse_Down.Y - pnt.Y * h_ratio)) 

     g.DrawRectangle(customPen, theRectangle) 

     'End If 

     g.Dispose() 

     pbZoneImage.Invalidate() 'draw img to picturebox 


    Catch ex As Exception 

    End Try 

End Sub 

我也试过刚刚结束的显示点(X,Y)的矩形的相对结束匹配,但同样不与比率工作。

任何有关如何使这项工作的想法,以及它在正常模式下,因为它在拉伸?我也打开不同的控制或一般的任何提示。谢谢!

+1

我已经通过您的文章了,你能短语问题用10-15字? – Neolisk 2014-10-20 17:31:02

+0

'* w_ratio'将会(显然)减少img缩放量的鼠标移动量。绘图应基于用户所看到的尺寸,然后您可能需要“放大”最终矩形以使其与实际图像尺寸相匹配。 – Plutonix 2014-10-20 17:37:27

+0

Tl; dr版本:我的图像很大,并且有很大的分辨率,所以使用“绘制图像”方法在其上绘制矩形会导致它不跟随鼠标,导致我的坐标点失效。 – Kat 2014-10-21 13:55:16

回答

1

这可以通过多种方式完成,但最简单的就是使用图片框SizeMode =正常。加载图片:

img = New Bitmap(pbZoneImage.Width, pbZoneImage.Height) 

imgClone = My.Resources.... 'real dimensions 

Dim g As Graphics = Graphics.FromImage(img) 

'it will scale the image, no need for stretch mode 
g.DrawImage(imgClone, 0, 0, pbZoneImage.Width, pbZoneImage.Height) 

g.Dispose() 

pbZoneImage.Image = img 

然后通常得出:

Private Sub DrawRectangle(ByVal pnt As Point) 

Try 
    Dim g As Graphics 

    g = Graphics.FromImage(img) 

    g.DrawImage(imgClone, 0, 0, pbZoneImage.Width, pbZoneImage.Height) 'we are clearing img with imgClone. imgClone contains the original image without the rectangles 

    Dim customPen As New Pen(currentColor, 5) 

    'If pnt.X = mouse_Down.X Or pnt.Y = mouse_Down.Y Then 
    ' g.DrawLine(customPen, mouse_Down.X, mouse_Down.Y, pnt.X * w_ratio, pnt.Y * h_ratio) 

    'Else 
    theRectangle = New Rectangle(Math.Min(mouse_Down.X, pnt.X), Math.Min(mouse_Down.Y, pnt.Y), 
       Math.Abs(mouse_Down.X - pnt.X), Math.Abs(mouse_Down.Y - pnt.Y)) 

    g.DrawRectangle(customPen, theRectangle) 

    'End If 

    g.Dispose() 

    pbZoneImage.Invalidate() 'draw img to picturebox 


    Catch ex As Exception 

    End Try 

End Sub 

mouse up event规模得到正确的结果:

Private Sub pbZoneImage_MouseUp(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles pbZoneImage.MouseUp 
    Dim width, height As Integer 

    width = CInt(Math.Abs(mouse_Down.X - e.X) * (imgClone.Width/pbZoneImage.Width)) 
    height = CInt(Math.Abs(mouse_Down.Y - e.Y) * (imgClone.Height/pbZoneImage.Height)) 

    TextBox1.Text = width.ToString + " " + height.ToString 
End Sub 
+0

我从来没有想过要事先收缩图像!这让我感觉像个假人。 – Kat 2014-10-21 14:14:38