I am trying to place a transparent image over two adjacent controls that have different background colors.
I want the image to remain transparent, meaning the Image needs to show the backcolor of each control.
The controls are two Panels set to different background colors and the Image (PictureBox or otherwise) is placed between the two panel controls.
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
Let's try this.
TPanel
and paste in the custom Panel class you can find below, overwriting the existing definition.TPanel
control in the ToolBox and drop one instance inside a Form.TPanel
and insert this code inside the handler method: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
TPanel
)panColored1
and panColored2
are supposed to be the names of the two existing Panels where the Image must be positioned. The sample code positions the Image in the middle of the 2 Panels, using TPanel1.Location( (...) )
Private imgBasketBall As Bitmap = Nothing
Public Sub New()
InitializeComponent()
imgBasketBall = DirectCast(Image.FromStream(New MemoryStream(File.ReadAllBytes("basketball.png"))), 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
Result:
Bitmap Size Bitmap Size
(1245x1242) (1178x2000)
The TPanel
(Transparent Panel) class:
Imports System.ComponentModel
<DesignerCategory("Code")>
Public Class TPanel
Inherits Panel
Private Const WS_EX_TRANSPARENT As Integer = &H20
Public Sub New()
SetStyle(ControlStyles.AllPaintingInWmPaint Or
ControlStyles.UserPaint Or
ControlStyles.Opaque Or
ControlStyles.ResizeRedraw, True)
SetStyle(ControlStyles.OptimizedDoubleBuffer, False)
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