Прозрачное изображение на двух элементах управления с разными цветами спины - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь разместить прозрачное изображение над двумя смежными элементами управления, которые имеют разные цвета фона.
Я хочу, чтобы изображение оставалось прозрачным, то есть на изображении должен отображаться задний цвет каждого элемента управления.

Элементами управления являются две панели, настроенные на разные цвета фона, и изображение (PictureBox или другое) размещается между двумя элементами управления панели.

Public Class frmMain 
    Private Img1 As Image = Image.FromFile("C:\xxxx.png") 

    Private Sub frmMain_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint 
        e.Graphics.DrawImage(Img1, 5, 5) 
    End Sub 
End Class

enter image description here

Ответы [ 2 ]

0 голосов
/ 19 января 2019

Есть также кое-что, что вы также можете попробовать. Это может быть не профессионально, но это работает. Разделите изображения на две половины. Нарисуйте первую половину на одной из панелей и вторую половину на другой панели. Обязательно импортируйте System.IO в ваш проект.

Код для разбиения выглядит следующим образом:

Imports System.IO
...
Public Function SplitImage(ByVal imgpath As String) As Image()
    Dim img As Image = Image.FromFile(imgpath)
    Dim bmp As Bitmap = DirectCast(img, Bitmap)
    Dim i As Integer = bmp.Height / 2
    Dim image1 As Bitmap = New Bitmap(bmp.Width, i)
    Dim image2 As Bitmap = New Bitmap(bmp.Width, i)
    Dim yPos As Integer = 0
    For x As Integer = 0 To image1.Width - 1
        For y As Integer = 0 To image1.Height - 1
            image1.SetPixel(x, y, bmp.GetPixel(x, y))
            yPos = y
        Next
    Next
    yPos += 1
    Dim ycount As Integer = 0
    For x As Integer = 0 To image2.Width - 1
        For y As Integer = yPos To bmp.Height - 1
            If ycount = i Then
                ycount -= 1
            End If
            image2.SetPixel(x, ycount, bmp.GetPixel(x, y))
            ycount += 1
        Next
        ycount = 0
    Next
    Dim ms As MemoryStream = New MemoryStream
    Dim ms1 As MemoryStream = New MemoryStream
    image1.Save(ms, Imaging.ImageFormat.Png)
    image2.Save(ms1, Imaging.ImageFormat.Png)
    Dim returnedImage(2) As Image
    returnedImage(0) = image1
    returnedImage(1) = image2
    Return returnedImage
End Function

Создайте на панели две панели (Panel1 и Panel2) и кнопку (Button1). Разместите две панели так, как вы хотите, установите для свойства BackgroundImageLayout панелей значение StretchImage. Затем из вашего кода вы можете вызвать такую ​​функцию, т. Е. Из события нажатия кнопки:

Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim pic() As Image = SplitImage("C:\xxxx.png")
    Panel1.BackgroundImage = pic(0)
    Panel2.BackgroundImage = pic(1)
End Sub

Для получения дополнительной информации о классе Bitmap, перейдите по этой ссылке Bitmap Class

0 голосов
/ 19 января 2019

Давайте попробуем это.

  • Создайте новый класс в Project, назовите его TPanel и вставьте в пользовательский класс Panel, который вы можете найти ниже, переписав существующее определение.
  • Скомпилируйте проект, затем найдите новый элемент управления TPanel в панели инструментов и поместите один экземпляр в форму.
    На форме , а не внутри одной из цветных панелей, иначе она станет дочерней для другого элемента управления и будет ограничена внутри своих границ.
  • Добавьте обработчик события к событию Paint TPanel и вставьте этот код в метод обработчика:

Private Sub TPanel1_Paint(sender As Object, e As PaintEventArgs) Handles TPanel1.Paint
    Dim canvas As Control = DirectCast(sender, Control)
    Dim rect As Rectangle = ScaleImageFrame(imgBasketBall, canvas.ClientRectangle)

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
    e.Graphics.CompositingMode = CompositingMode.SourceOver
    e.Graphics.PixelOffsetMode = PixelOffsetMode.Half
    e.Graphics.DrawImage(imgBasketBall, rect)
End Sub

Private Function ScaleImageFrame(sourceImage As Bitmap, destinationFrame As Rectangle) As Rectangle
    Dim rect As RectangleF = New RectangleF(0, 0, sourceImage.Width, sourceImage.Height)
    'Define the ratio between the Image Rectangle and the Container ClientRectangle
    Dim ratio As Single = CType(Math.Max(destinationFrame.Width, destinationFrame.Height) /
                                Math.Max(rect.Width, rect.Height), Single)
    rect.Size = New SizeF(rect.Width * ratio, rect.Height * ratio)
    'Use Integer division to avoid negative values
    rect.Location = New Point((destinationFrame.Width - CInt(rect.Width)) \ 2,
                              (destinationFrame.Height - CInt(rect.Height)) \ 2)
    Return Rectangle.Round(rect)
End Function
  • В форме создайте экземпляр объекта Bitmap, который будет содержать изображение; также установите расположение панели (TPanel)
    Элементы управления panColored1 и panColored2 должны быть именами двух существующих панелей, на которых должно быть расположено изображение. Пример кода размещает изображение в центре двух панелей, используя TPanel1.Location( (...) )

Private imgBasketBall As Bitmap = Nothing

Public Sub New()
    InitializeComponent()
    imgBasketBall = DirectCast(Image.FromFile("basketball.png").Clone(), Bitmap)
    TPanel1.Size = New Size(120, 120)
    TPanel1.Location = New Point(panColored1.Left + (panColored1.Width - TPanel1.Width) \ 2,
                                 panColored1.Top + (panColored1.Height + panColored2.Height - TPanel1.Height) \ 2)
    TPanel1.BringToFront()
End Sub

Результат:

Transparent Panel Scaled Image

      Bitmap Size           Bitmap Size 
      (1245x1242)           (1178x2000)

Класс TPanel (прозрачная панель):

Imports System.ComponentModel

<DesignerCategory("Code")>
Public Class TPanel
    Inherits Panel
    Private Const WS_EX_TRANSPARENT As Integer = &H20
    Public Sub New()
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or
                    ControlStyles.UserPaint Or
                    ControlStyles.Opaque Or
                    ControlStyles.ResizeRedraw, True)
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
        Me.UpdateStyles()
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        e.Graphics.FillRectangle(Brushes.Transparent, Me.ClientRectangle)
        MyBase.OnPaint(e)
    End Sub

    Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim parameters As CreateParams = MyBase.CreateParams
            parameters.ExStyle = parameters.ExStyle Or WS_EX_TRANSPARENT
            Return parameters
        End Get
    End Property
End Class
...