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
答案 0 :(得分:2)
让我们尝试一下。
TPanel
,然后粘贴到您可以在下面找到的自定义Panel类中,覆盖现有定义。 TPanel
控件,并将一个实例拖放到Form中。TPanel
的Paint事件中,并将此代码插入处理程序方法中:
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
和 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
结果:
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
答案 1 :(得分:0)
还有一些您也可以尝试的方法,它虽然不专业,但是可以工作。将图像分成两半。在其中一个面板上绘制前半部分,在另一个面板上绘制后半部分。
确保将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)和一个Button(Button1)。
将两个面板放置在所需的位置,将面板的BackgroundImageLayout
属性设置为StretchImage
。
然后从您的代码中可以像这样调用函数,即从Button的click事件:
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