4

これが私が達成しようとしていることのイメージです:

http://www.findmysoft.com/img/news/Windows-7-Beta-1-with-Updated-Boot-Screen-Drops-Next-Month.jpg

ご覧のとおり、プログレスバーの下にわずかな反射があります。

このコードに大きく基づいたカスタムプログレスバーがあります:http:
//www.codeproject.com/Articles/19309/Vista-Style-Progress-Bar-in-C

注:私のコードはVBです。

問題-その下にプログレスバーの反射を描画して、上記の画像のように見せたいと思います。そのための1つの方法は、手動で行う必要のあるピクセルを使用することだと言われています。それが唯一の選択肢ですか?それを行う他の/より簡単な方法はありますか?

私はあなたの助けに感謝します。ありがとう!

4

2 に答える 2

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)

これらの2つで:

Dim greyScale As Integer = CInt(clr.R * 0.3 + clr.G * 0.59 + clr.B * 0.11)
clr = Color.FromArgb(alpha, greyScale, greyScale, greyScale)

次のようなものが表示されます。

ここに画像の説明を入力してください

パラメータを操作して、シャドウをよりリアルにすることができます。

ソリューションはこの記事に基づいています:

VB.NETでグラデーションアルファ(不透明度)値を使用して画像を描画します

于 2012-11-10T23:28:25.127 に答える
2

このソリューションはより多くのコードを提供しますが、GetPixel/SetPixelよりも何倍も高速です。それ以上の設定なしで1つのオーバーロードがあります。または、アルファの開始値と停止値、および反射を「スクイーズ」する量で使用できます。

オーバーロードされた単純なバージョンは、背景色が親の色であると想定しています。エラーチェックはありませんのでご注意ください。もちろん、これを本番コードに実装する必要があります。

結果は次のようになります:(コードから画像を生成するための余分な問題を経験してくれた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
于 2012-11-11T08:29:06.063 に答える