获取面板覆盖的PictureBox区域

时间:2009-06-17 19:40:12

标签: .net winforms user-interface

我有两个控件都包含在用户控件中。

  • 小组位置:49,400
  • 面板尺寸:787,70
  • Picturebox位置:25,0
  • Picturebox尺寸:737,700

在面板下方可以看到Picturebox。

我可以使用一些建议来确定面板所覆盖的PictureBox图像区域的最佳方法,这样我就可以在DrawImage调用中正确地将图像复制到面板上。

我的回答是:我将从这个区域复制屏幕:左上方24,400,宽714,高70 但是,如何使用面板和图片框的任意组合进行自动化以实现可重复使用的控制?

背景如果您需要更多信息:PictureBox包含地图的图像。该面板包含用于操作地图的工具,面板位于PictureBox的顶部。面板需要是半透明的,因此仍然可以看到地图图像。

由于winforms绘制透明度的方式,(通过控制树调用让父绘制自己) - 当我绘制我的面板时,它采用用户控件背景的颜色,而不是图像的在它下面的地图。

我对此的想法是:如果我可以将面板下方的地图图像复制到面板的背景,然后绘制我的半透明背景,我将能够模拟设计师要求的效果。

面板中的原始代码是我从图片框中抓取图像的地方。

            Dim x As Integer = GetXOffset()
            Dim y As Integer = GetYOffset()

            Dim sizeOfImage As Size = New Size(ClientRectangle.Width _
                                  , ClientRectangle.Height)
            bmpScreenshot = New Bitmap(sizeOfImage.Width, sizeOfImage.Height, _
                     PixelFormat.Format32bppArgb)

            gfxScreenshot = Graphics.FromImage(bmpScreenshot)
            Dim destrect As New Rectangle(ClientRectangle.X, ClientRectangle.Y, _
                        ClientRectangle.Width, ClientRectangle.Height)


            gfxScreenshot.DrawImage(mPictureBox1.Image, destrect, New Rectangle(x, y, _
               sizeOfImage.Width, sizeOfImage.Height), GraphicsUnit.Pixel)

我将此图像复制到OnPaint事件的背景中。

If bmpScreenshot Is Nothing Then
            PushScreen()
        End If
        If Not bmpScreenshot Is Nothing Then
            pevent.Graphics.DrawImage(bmpScreenshot, GetPaintOffset())
        End If

最后,在从接受的答案中添加更改后,这里是修改后的代码,其中抓取了图像。

 Dim sizeOfImage As Size = New Size(ClientRectangle.Width _
                                  , ClientRectangle.Height)
            bmpScreenshot = New Bitmap(sizeOfImage.Width, sizeOfImage.Height, PixelFormat.Format32bppArgb)

            gfxScreenshot = Graphics.FromImage(bmpScreenshot)

            Dim rect As Rectangle = Rectangle.Intersect(mPictureBox1.Bounds, Bounds)
            Dim destrect As Rectangle = New Rectangle(rect.Left - Left, _
             rect.Top - Top, rect.Width, rect.Height)
            Dim imgrect As Rectangle = _
              New Rectangle(rect.Left - mPictureBox1.Bounds.Left, _
              rect.Top - mPictureBox1.Bounds.Top, rect.Width, rect.Height)

            gfxScreenshot.DrawImage(mPictureBox1.Image, destrect, _
               imgrect, GraphicsUnit.Pixel)

1 个答案:

答案 0 :(得分:3)

您可以使用Rectangle.Intersect方法(连同一点点计算)来获得所需的结果。 C#样本:

Rectangle rect = Rectangle.Intersect(_pictureBox.Bounds, _panel.Bounds);
rect = new Rectangle(rect.Top - _panel.Top, rect.Left - _panel.Left, rect.Width, rect.Height);
e.Graphics.FillRectangle(Brushes.Red, rect);

<强>更新

我更多地使用了这个,并提出了以下解决方案,我发现它更简单,也更健壮(这次是VB.NET代码):

Private Sub DrawPanelBackground(ByVal pictureBox As PictureBox, ByVal panel As Panel)
    If pictureBox.Image Is Nothing Then
        Exit Sub
    End If

    Dim rect As Rectangle = New Rectangle(pictureBox.Left - panel.Left, pictureBox.Top - panel.Top, pictureBox.Image.Width, pictureBox.Image.Height)
    Using g As Graphics = Panel.CreateGraphics()
        g.DrawImage(pictureBox.Image, rect)
    End Using
End Sub