这是我想要实现的目标的图像:
正如您所看到的,进度条下有一点反映。
我有一个很大程度上基于此代码的自定义进度条:
http://www.codeproject.com/Articles/19309/Vista-Style-Progress-Bar-in-C
注意:我的代码是VB。
问题 - 我想在其下面绘制一个进度条的反映,因此它看起来与我上面给出的图像类似。我被告知,一种方法是使用像素,这需要手动完成。这是唯一的选择吗?还有其他/更简单的方法吗?
感谢您的帮助。 谢谢!
答案 0 :(得分:8)
你在找这样的东西吗?
以下是代码:
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))
如果您想要灰度阴影,请替换此行
clr = Color.FromArgb(alpha, clr.R, clr.G, clr.B)
这两个:
Dim greyScale As Integer = CInt(clr.R * 0.3 + clr.G * 0.59 + clr.B * 0.11)
clr = Color.FromArgb(alpha, greyScale, greyScale, greyScale)
你会得到这样的东西:
您可以使用参数来使阴影更逼真。
解决方案基于这篇文章:
Draw an image with gradient alpha (opacity) values in VB.NET
答案 1 :(得分:2)
此解决方案可提供更多代码,但速度比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