Answered by:
RenderTargetBitmap, whats going on?

Question
-
Hi
I try to make a copy of an element with some text elements inside, but when I use RenderTargetBitmap then my output gets very blurry. Please help, I've been trying everything but the right solution, for the last 3 days.
PLEASE HELP ME.
I've made an little example to show my problem.
XAML
Code Snippet<
Windowxmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns
:x="http://schemas.microsoft.com/winfx/2006/xaml"x
:Class="CopyExample.Window1"x
:Name="Window"Title
="Window1"Width
="640" Height="480" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"><Grid HorizontalAlignment="Left" x:Name="MyGrid" VerticalAlignment="Top" Width="198" Height="155" Background="#FFA9FFE5">
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap" Margin="0,23.94,0,0"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap" Margin="0,47.88,0,0"/>
<TextBlock HorizontalAlignment="Left" FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap" Margin="0,71.82,0,59.24" d:LayoutOverrides="Height"/>
</Grid><Rectangle HorizontalAlignment="Left" VerticalAlignment="Top" Width="{Binding Path=ActualWidth, ElementName=MyGrid, Mode=Default}" Height="{Binding Path=ActualHeight, ElementName=MyGrid, Mode=Default}" Fill="#FFFF0000" Stroke="{x:Null}" x:Name="MyMirror" StrokeThickness="0" Visibility="Hidden"/>
<Button HorizontalAlignment="Left" Margin="8,171,0,0" VerticalAlignment="Top" Width="94" Height="29" Content="Make Mirror" Click="Button_Click"/>
</Window>
Code behind
Code Snippetusing
System;using
System.Collections.Generic;using
System.Linq;using
System.Text;using
System.Windows;using
System.Windows.Controls;using
System.Windows.Data;using
System.Windows.Documents;using
System.Windows.Input;using
System.Windows.Media;using
System.Windows.Media.Imaging;using
System.Windows.Shapes;namespace
CopyExample{
/// <summary> /// Interaction logic for Window1.xaml /// </summary>{
{
}
{
source.UpdateLayout();
(
int)size.Width, (int)size.Height, 96, 96, PixelFormats.Pbgra32);rtb.Render(source);
return rtb;}
{
{
MyMirror.Visibility =
MyMirror.Fill =
new ImageBrush(CopyElement(MyGrid));}
elseMyMirror.Visibility =
}
}
}
Friday, April 18, 2008 6:56 PM
Answers
-
And one thing you need to know is that when the text is realized/rasterized into RenderTargetBitmap, the cleartype rendering algorithm will fallback to grayscale antialiasing which doesn't have the same text rendering quality of the original visuals.
Hope this helps- Marked as answer by spandy Wednesday, June 18, 2008 5:45 AM
Monday, April 21, 2008 8:20 AM
All replies
-
Try using explicit measurement of your source element before rendering to bitmap.
Here's a sample on rendefing a Canvas to .png image
Saving you canvas to image, XPS document or raw Xaml.
http://dvuyka.spaces.live.com/blog/cns!305B02907E9BE19A!240.entry
Friday, April 18, 2008 7:30 PM -
Hi Denis Vuyka
Thanks for your response, but it didn't do the trick, the output brush is still blurry and doesn't look like the source element..
I've changed CopyElement to:
Code Snippetpublic BitmapSource CopyElement(FrameworkElement source)
{
source.UpdateLayout();
// Save current source transform
Transform transform = source.LayoutTransform;// reset current transform (in case it is scaled or rotated)
source.LayoutTransform =
null;// Get the size of source
Size size = new Size(source.Width, source.Height);// Measure and arrange the source
// VERY IMPORTANTsource.Measure(size);
source.Arrange(
new Rect(size));// Create a render bitmap and push the source to it
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96d, 96d, PixelFormats.Pbgra32);renderBitmap.Render(source);
source.LayoutTransform = transform;
return renderBitmap;}
Friday, April 18, 2008 7:48 PM -
Anyone??? I'm pretty stocked here
When I try to make a rectangle with fill set as a visual brush pointing at MyGrid, it looks perfect. How can I get the same effect using RenderTargetBitmap?
Can you get my sample to work, and you will be my new best friend ;-)
Spandy
Friday, April 18, 2008 11:16 PM -
I think you are searching the problems in the wrong place. Guess this is layouting problem but not the rendering.
Try making your Rectangle Visible and test the rendering
<
Rectangle HorizontalAlignment="Left" VerticalAlignment="Top" Width="{Binding Path=ActualWidth, ElementName=MyGrid, Mode=Default}" Height="{Binding Path=ActualHeight, ElementName=MyGrid, Mode=Default}" Fill="#FFFF0000" Stroke="{x:Null}" x:Name="MyMirror" StrokeThickness="0" Visibility="Visible"/>I've set the Visibility to "Visible" and rendering is not blurry.
Also I've used either the last code (from the article) wrapped with your method
MyMirror.Visibility =
Visibility.Visible;MyMirror.Fill =
new ImageBrush(CopyElement(MyGrid));and another lightweight one
MyMirror.Visibility =
Visibility.Visible;VisualBrush
vb = new VisualBrush(MyGrid);vb.Viewbox =
new Rect(new Size(MyGrid.ActualWidth, MyGrid.ActualHeight));vb.Viewport =
new Rect(new Size(MyGrid.ActualWidth, MyGrid.ActualHeight));MyMirror.Fill = vb;
and both rendering fine.
Try elaborating on the layout as this is the root of your problem
Saturday, April 19, 2008 8:28 AM -
Hi Denis Vuyka
I've done the above, but with no luck. I've made some small changes in the xaml, so you can see the blurry stuff a little better. I want the output to be exactly like the element, for that reason I've put the rectangle on top of the element, so I can see the difference. The textbox elements inside the MyGrid is jumping around and is very blurry on the MyMirror.
Can you please try this Xaml then you know exactly what I mean.
XAML
Code Snippet<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="CopyExample.Window1"
x:Name="Window"
Title="Window1"
Width="640" Height="480" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"><Grid x:Name="LayoutRoot">
<Grid HorizontalAlignment="Left" x:Name="MyGrid" VerticalAlignment="Top" Width="198" Height="167" Background="#FFA9FFE5">
<Border Margin="59.153,0,23.154,0" BorderThickness="2,2,2,2" BorderBrush="#FF000000" CornerRadius="5,5,5,5">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Grid HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="Auto">
<TextBlock Margin="0,0,0,8" FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap"/>
<TextBlock FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap" Margin="0,55.06,0,76"/>
<TextBlock FontSize="18" Foreground="#FFFF0000" Text="TextBlock" TextWrapping="Wrap" Height="23.94" VerticalAlignment="Bottom" Margin="0,0,0,48"/>
<TextBlock FontSize="18" Foreground="#FF000000" Text="TextBlock" TextWrapping="Wrap" Height="23.94" VerticalAlignment="Bottom" Margin="0,0,0,23"/>
</Grid>
</Border>
</Grid>
<Rectangle
VerticalAlignment="Top"
Width="{Binding Path=ActualWidth, ElementName=MyGrid, Mode=Default}"
Height="{Binding Path=ActualHeight, ElementName=MyGrid, Mode=Default}"
Fill="#FFFF0000"
Stroke="{x:Null}"
x:Name="MyMirror"
StrokeThickness="0"
Visibility="Visible" HorizontalAlignment="Left"/>
<Button HorizontalAlignment="Left" Margin="8,171,0,0" VerticalAlignment="Top" Width="94" Height="29" Content="Make Mirror" Click="Button_Click"/>
</Grid>
</Window>Saturday, April 19, 2008 9:29 AM -
Guess this is some kind of issue related to color rendering or clear types. Try setting the Black color for your TexBlocks and there won't be blurring. Guess this requires further elaboration on the rendering process related to text
Saturday, April 19, 2008 1:11 PM -
Try creating the RenderTargetBitmap with the Size of the Target instead of the Size of the Source (as you do in CopyElement), at least as an experiment. You may be getting artifacts of stretching.Sunday, April 20, 2008 2:11 PM
-
Can you also compare the behavior on both Vista and XP pro? Something tells me it might be different
Sunday, April 20, 2008 4:55 PM -
And one thing you need to know is that when the text is realized/rasterized into RenderTargetBitmap, the cleartype rendering algorithm will fallback to grayscale antialiasing which doesn't have the same text rendering quality of the original visuals.
Hope this helps- Marked as answer by spandy Wednesday, June 18, 2008 5:45 AM
Monday, April 21, 2008 8:20 AM -
Thanks John Gossman, I'll try this when I get home from work.Wednesday, April 23, 2008 12:46 PM
-
Denis Vuyka
You are right, I tried it on a windows XP and it helped on the blurry stuff. It only seems to get blurry on my windows vista.
Spandy
Wednesday, April 23, 2008 12:50 PM -
Thanks Marco Zhou
Is there an other way to have the quality the same? I'm making a bookflipper, and I need to get a copy of the current render output, so I can use this as the flipping page.
Spandy
Wednesday, April 23, 2008 12:53 PM -
Hi Marco / spandy,
I know this is an old post, but did you ever find a way to render text to an image without the cleartype down scaling?
I wondered if there was an alternative to RenderTargetBitmap
all the best
tommy
Sunday, March 13, 2011 7:46 PM