【问题标题】:Get the area of a PictureBox which is covered by a panel获取面板覆盖的 PictureBox 的区域
【发布时间】:2010-11-03 19:02:51
【问题描述】:

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

  • 面板位置:49、400
  • 面板尺寸:787、70
  • 图片框位置:25, 0
  • 画框大小:737、700

图片框位于面板下方。

我可以使用一些建议来确定面板覆盖的 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)

【问题讨论】:

    标签: .net winforms user-interface


    【解决方案1】:

    您可以使用 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
    

    【讨论】:

    • 如果 Panel 和 PictureBox 共享父控件(可能是用户控件),则 Control.Bounds 方法将准确提供所需的内容。
    • 谢谢,我会在不同的控制位置试一试,让你知道!
    • 编辑显示我“认为”会假设面板始终位于图片框内的代码。如果面板左上角在图片框矩形之外怎么办?
    • @BPerreault:在第二个版本中,我尝试让面板从各个方向“伸出”在图片框的边缘,并且在所有情况下都运行良好。
    • 哦,我不知道我做错了什么......无论如何,谢谢你,只要面板完全在图片框的范围内,我就没有问题了修复。
    猜你喜欢
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 2012-08-04
    • 1970-01-01
    • 2015-06-24
    • 2023-04-06
    相关资源
    最近更新 更多