这是我要实现的目标的图像:
如您所见,进度条下方有轻微的反射。
我有一个很大程度上基于此代码的自定义进度条:http:
//www.codeproject.com/Articles/19309/Vista-Style-Progress-Bar-in-C
注意:我的代码在 VB 中。
问题- 我想在它下面绘制一个进度条的反射,这样它看起来类似于我上面给出的图像。有人告诉我,一种方法是使用像素,这需要手动完成。那是唯一的选择吗?还有其他/更简单的方法吗?
我感谢您的帮助。谢谢!
这是我要实现的目标的图像:
如您所见,进度条下方有轻微的反射。
我有一个很大程度上基于此代码的自定义进度条:http:
//www.codeproject.com/Articles/19309/Vista-Style-Progress-Bar-in-C
注意:我的代码在 VB 中。
问题- 我想在它下面绘制一个进度条的反射,这样它看起来类似于我上面给出的图像。有人告诉我,一种方法是使用像素,这需要手动完成。那是唯一的选择吗?还有其他/更简单的方法吗?
我感谢您的帮助。谢谢!
Are you looking for something like this?
Here is the code:
Dim pgBarReflection As New Bitmap(ProgressBar1.Width, 20)
ProgressBar1.DrawToBitmap(pgBarReflection, ProgressBar1.ClientRectangle)
For x As Integer = 0 To pgBarReflection.Width - 1
For y As Integer = 0 To pgBarReflection.Height - 1
Dim alpha = 255 - 255 * y \ pgBarReflection.Height
Dim clr As Color = pgBarReflection.GetPixel(x, y)
clr = Color.FromArgb(alpha, clr.R, clr.G, clr.B)
pgBarReflection.SetPixel(x, y, clr)
Next y
Next x
Me.CreateGraphics.DrawImage(pgBarReflection, New Point(ProgressBar1.Left, ProgressBar1.Bottom + 10))
If you want greyscale shadow, replace this line
clr = Color.FromArgb(alpha, clr.R, clr.G, clr.B)
with these two:
Dim greyScale As Integer = CInt(clr.R * 0.3 + clr.G * 0.59 + clr.B * 0.11)
clr = Color.FromArgb(alpha, greyScale, greyScale, greyScale)
You will get something like this:
You can play with parameters to make the shadow more realistic.
Solution is based on this article:
Draw an image with gradient alpha (opacity) values in VB.NET
此解决方案提供更多代码,但比 GetPixel/SetPixel 快很多倍。它有一个过载而没有任何进一步的设置,或者您可以将它与 alpha 开始和停止值以及您想要“挤压”反射的程度一起使用。
重载的简单版本假定背景颜色是父对象的颜色。请注意,它没有错误检查。您当然需要在生产代码中实现这一点。
结果将是这样的:(非常感谢 Neolisk 经历了从代码生成图像的额外麻烦)
仍有优化空间(仅使用“压缩”版本,取消装箱计算等),但我将把它留给用户执行 :-)
Private Sub DrawControlReflection(c As Control)
DrawControlReflection(c, c.Parent.BackColor, 1, 0, 1, 7) 'set you defaults here
End Sub
''' <summary>
''' Draws an reflection of a control
''' </summary>
''' <param name="c">The control to make an reflection of</param>
''' <param name="bgCol">Background color in transparent area</param>
''' <param name="startTrans">0.0-1.0, start value of reflection transparency, usually 1</param>
''' <param name="endTrans">0.0-1.0, end value of reflection transparency, usually 0</param>
''' <param name="squeeze">height of reflection, values 0-1, 1=100%, 0.5=50% etc.</param>
''' <param name="delta">y offset of reflection from control's bottom</param>
''' <remarks>
''' Provided AS-IS.
''' Created by Epistmex, use as you want.
''' Need implementation of error checking (bitmap allocations etc.)
''' </remarks>
Private Sub DrawControlReflection(c As Control,
bgCol As Color,
startTrans As Single,
endTrans As Single,
squeeze As Single,
delta As Integer)
'
'-- Original control's bound
'
Dim r As Rectangle = c.ClientRectangle
'
'-- Destination bound
'
Dim rd As Rectangle = New Rectangle(c.Left,
c.Top + r.Height + 1 + delta,
r.Width,
CInt(r.Height * squeeze))
'
'-- Create a bitmap for reflection and copy control content into it
'
Dim bmp As New Bitmap(r.Width,
r.Height,
Imaging.PixelFormat.Format24bppRgb)
c.DrawToBitmap(bmp, r)
'
'-- flip it vertically
'
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY)
'
'-- Add gradient "transparency" to bitmap
'
AddGradientAlpha(bmp, r, startTrans, endTrans, bgCol)
'
'-- Draw the result
'
Dim g As Graphics = c.Parent.CreateGraphics
if squeeze <> 1 Then g.InterpolationMode = _
Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(bmp, rd)
g.Dispose()
bmp.Dispose()
End Sub
Private Sub AddGradientAlpha(ByRef bmp As Bitmap, r As Rectangle, s As Single, e As Single, bc As Color)
Dim bmpLock As Imaging.BitmapData = bmp.LockBits(r, Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
Dim st As Integer = bmpLock.Stride
Dim bytesBmp(bmpLock.Stride * bmp.Height) As Byte
Runtime.InteropServices.Marshal.Copy(bmpLock.Scan0, bytesBmp, 0, bytesBmp.Length)
'
'-- Calculate and create pre-multiplied gradient alpha
'
Dim x, y, dx, l, d As Integer
Dim aDiff As Double = s - e
Dim a As Double
Dim b As Byte
Dim h As Integer = bmp.Height - 1
For y = 0 To h
l = y * st 'line. cache the calculations we can
d = h - y 'position with opposite value
If d = 0 Then
a = e
Else
a = (aDiff * d / h) + e 'gradient value ad 0.5 to h for even more accuracy
End If
If a < 0 Then a = 0
If a > 1 Then a = 1
a = a * a 'power of 2 to make gradient steeper
For x = 0 To bmp.Width - 1
dx = l + x * 3 'x pos in buffer
'make gradient of colors in buffer + mix bg color
bytesBmp(dx) = CByte(bytesBmp(dx) * a + ((1 - a) * bc.B))
bytesBmp(dx + 1) = CByte(bytesBmp(dx + 1) * a + ((1 - a) * bc.G))
bytesBmp(dx + 2) = CByte(bytesBmp(dx + 2) * a + ((1 - a) * bc.R))
Next
Next
'
'-- Marshal back
'
Runtime.InteropServices.Marshal.Copy(bytesBmp, 0, bmpLock.Scan0, bytesBmp.Length)
bmp.UnlockBits(bmpLock)
End Sub