Categories: Blog

More on Silverlight 3’s Writeable Bitmap

One of the WPF features that I miss in Silverlight is VisualBrush. Among other things, VisualBrush makes it easy to generate simulated reflections. To create reflections in Silverlight, we typically declare a copy of all the XAML we want to reflect, use a ScaleTransform to flip the copy upside-down, and apply an Opacity or OpacityMask to complete the illusion.

In Silverlight 3, you can use the new WriteableBitmap class to generate reflections without duplicating any XAML. In addition to letting you create bitmapped images from scratch, WriteableBitmap features a Render method that you can use to render all or part of the visual tree to a bitmap. To generate a reflection, you simply declare an Image in the scene and position it where you want the reflection to appear, and then use WriteableBitmap.Render to render everything you want reflected into the Image.

To demonstrate, I built a sample whose XAML is structured like this:

<UserControl x:Class=”ReflectionDemo.MainPage”

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”>

    <Grid x:Name=”LayoutRoot” Background=”White”>

        <StackPanel Orientation=”Vertical” VerticalAlignment=”Center”>

 

            <!– XAML to be reflected –>

            <Canvas x:Name=”Penguin” Width=”340″ Height=”322″>

             

            </Canvas>

 

            <!– Reflection –>

            <Image x:Name=”Reflection” Stretch=”None”>

                <Image.RenderTransform>

                    <TransformGroup>

                        <TranslateTransform Y=”-322″ />

                        <ScaleTransform ScaleY=”-1″ />

                    </TransformGroup>

                </Image.RenderTransform>

                <Image.OpacityMask>

                    <LinearGradientBrush StartPoint=”0.0,0.0″ EndPoint=”0.0,1.0″>

                        <GradientStop Offset=”1.0″ Color=”#80000000″ />

                        <GradientStop Offset=”0.5″ Color=”#00000000″ />

                    </LinearGradientBrush>

                </Image.OpacityMask>

            </Image>

        </StackPanel>

    </Grid>

</UserControl> 

Then I added the following statements to MainPage’s constructor:

WriteableBitmap bitmap = new WriteableBitmap ((int)Penguin.Width,

    (int)Penguin.Height, PixelFormats.Bgr32);

bitmap.Render(Penguin, new TranslateTransform());

Reflection.Source = bitmap;

And here’s the result:

 

I could have built the transforms for the reflected image into the code, but I reasoned that it’s better to apply the transforms declaratively so you can control where and how the reflection is positioned. If you wanted to reflect around the Y-axis instead of the X, for example, you could simply change ScaleY=”-1″ to ScaleX=”-1″ in the ScaleTransform.

Jeff Prosise

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

2 weeks ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

3 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

1 month ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

2 months ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

2 months ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago