[当使用TransparencyKey
制作透明表格并将带有透明像素的PNG放置为背景图像时,PNG图像在其大部分图像轮廓上都有难看的彩色边缘(尤其是用于设置表格的颜色透明度键...在我的情况下(洋红色)。
我也尝试了好几个小时,但也没有找到解决方案。几乎起作用的是使用具有不同TransparencyKey
颜色的多个窗体,并且如果该像素与其他窗体之一中的颜色或位置不匹配,则逐个像素地匹配窗体,如果存在匹配则将其排除在外而将其写入像素在新表格上按像素排列。
这不是完美的,但是非常接近。但是,此方法花费了2.5个小时,对于处理一个小的徽标来说,这太长了。
如何解决此问题?
TransparencyKey
设置为与BackGroundColor
相同的颜色,然后在窗体的透明表面上绘制半透明的位图,位图的锯齿部分不会与Form后面的任何内容混合。用作TransparencyKey
的颜色可能会影响渲染结果,但是半透明像素(尤其是位图边缘附近的像素)将始终在不同背景上可见,因为没有blending。
要创建分层表单,我们可以设置系统会自动组成和重新绘制分层的窗口,基础应用程序的窗口。结果,分层的窗口是平滑呈现,没有复杂窗口典型的闪烁地区。此外,分层窗口可以是部分半透明的,也就是alpha混合。
WS_EX_LAYERED
扩展样式来覆盖表单的WS_EX_LAYERED
属性:Windows 8+:顶层窗口和子窗口支持Protected Overrides ReadOnly Property CreateParams As CreateParams
Get
Dim parms As CreateParams = MyBase.CreateParams
parms.ExStyle = parms.ExStyle Or WS_EX_LAYERED
Return parms
End Get
End Property
样式。以前的Windows版本仅对顶级窗口支持此样式。
要绘制可以与背景混合的位图,我们在窗口设备上下文中选择一个位图,然后调用WS_EX_LAYERED
,并使用UpdateLayeredWindow结构指定渲染的类型。此结构允许定义([BLENDFUNCTION
)源位图和目标位图如何混合(实际上,唯一可能的操作是Source Over,BLENDFUNCTION
),即应用于源的不透明度级别位图(BlendOp
:AC_SRC_OVER
=不透明,SourceConstantAlpha
=完全透明)以及如何解释源位图和目标位图的颜色(255
)。
0
AlphaFormat
(请参阅有关颜色如何显示的文档混合将根据源bItmap的“颜色”类型进行解释。 就这些。 [要构建分层表单,将新表单添加到项目,更改构造器,如下所示,添加AC_SRC_ALPHA
替代,如果可以移动拖动表单,则添加AlphaFormat
替代,并
CreateParams
WndProc
支持类添加到项目中:►可以像往常一样创建Form,在这种情况下,将Bitmap对象传递给其构造函数:(位图格式必须为32位SelectBitmap()
-具有alpha通道的NativeMethods
可以))ARGB
PNG
[Dim layeredForm As New PerPixelAlphaLayeredForm(bitmap)
layeredForm.Show()
支持类别:Public Class PerPixelAlphaLayeredForm
Public Sub New()
Me.New(Nothing)
End Sub
Public Sub New(bitmap As Bitmap)
InitializeComponent()
Me.LayerBitmap = bitmap
End Sub
Private ReadOnly Property LayerBitmap As Bitmap
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
If Me.LayerBitmap IsNot Nothing Then
Me.ClientSize = Me.LayerBitmap.Size
Dim screenSize = Screen.FromHandle(Me.Handle).Bounds.Size
Me.Location = New Point((screenSize.Width - Me.Width) \ 2, (screenSize.Height - Me.Height) \ 2)
SelectBitmap(Me.LayerBitmap)
' Or, call the SelectBitmapFadeOut() method
' Task.Run(Function() SelectBitmapFadeOut(Me.LayerBitmap))
End If
Me.TopMost = True
End Sub
Private Sub SelectBitmap(bitmap As Bitmap)
NativeMethods.SelectBitmapToLayeredWindow(Me, bitmap, 255)
End Sub
Private Async Function SelectBitmapFadeOut(bitmap As Bitmap) As Task
Dim fadeProgress As Integer = 255
For i = fadeProgress To 1 Step -1
BeginInvoke(New MethodInvoker(Sub() NativeMethods.SelectBitmapToLayeredWindow(Me, bitmap, fadeProgress)))
fadeProgress -= 1
Await Task.Delay(10)
Next
End Function
Protected Overrides ReadOnly Property CreateParams As CreateParams
Get
Dim parms As CreateParams = MyBase.CreateParams
If Not DesignMode Then parms.ExStyle = parms.ExStyle Or NativeMethods.WS_EX_LAYERED
Return parms
End Get
End Property
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = NativeMethods.WM_NCHITTEST Then
m.Result = New IntPtr(NativeMethods.HTCAPTION)
Else
MyBase.WndProc(m)
End If
End Sub
End Class
您可以从Google云端硬盘下载NativeMethods
。内置.Net Framework 4.7.2-其他任何4.5.2+框架都可以使用