Получить область PictureBox, которая покрыта панелью - PullRequest
0 голосов
/ 17 июня 2009

У меня есть два элемента управления, которые оба содержатся в пользовательском элементе управления.

  • Расположение панели: 49, 400
  • Размер панели: 787, 70
  • Местоположение Picturebox: 25, 0
  • Размер фотобокса: 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 Ответ

3 голосов
/ 17 июня 2009

Вы можете использовать метод 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...