使用RenderTargetBitmap渲染画布会产生模糊的图像 [英] Rendering Canvas with RenderTargetBitmap is giving blurry images
问题描述
我正在使用画布制作绘图程序并将其渲染到自身,但每次使用RenderTargetBitmap进行渲染时,我的图像变得模糊,并且使用更大的画布会更多地发生。
I am making a drawing program using canvas and rendering it on to itself but every time I render using RenderTargetBitmap my image become blurry and it happens more with bigger canvas.
过去还有另一个问题,每当我渲染我的图像时,都会向右下方移动,但由于stackoverflow的帮助,它已得到修复。
In the past there was another problem where every time I render my image get shifted toward bottom right but it was fixed thanks to help on stackoverflow.
这是我过去的问题: RenderTargetBitmap
图像滑动
这是我的代码:
Here is my Code:
XAML:
<网格>
  ;< Grid.RowDefinitions>
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;< RowDefinition高度=" 25" />
&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;&NBSP;< RowDefinition高度=" 50" />
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;< RowDefinition高度=" * QUOT ; />
< RowDefinition Height =" 25" />
&NBSP;< /Grid.RowDefinitions>
&NBSP;&NBSP;&NBSP;&NBSP;< Grid.ColumnDefinitions>
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;< ColumnDefinition宽度=" 50" />
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;< ColumnDefinition宽度=" * QUOT; />
< ColumnDefinition Width =" 150" />
< / Grid.ColumnDefinitions>
$
&NBSP; &NBSP; &NBSP; < ScrollViewer Grid.Row =" 2" Grid.Column =" 1"
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; HorizontalScrollBarVisibility = QUOT;自动" VerticalScrollBarVisibility =" Auto">
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < Canvas x:Name =" Pad"可聚焦= QUOT;真" FocusManager.IsFocusScope = QUOT;真"宽度= QUOT; 700"高度="500"左右b $ b &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;的MouseDown = QUOT; Pad_MouseDown"的MouseMove = QUOT; Pad_MouseMove" MouseUp =" Pad_MouseUp"
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; SnapsToDevicePixels = QUOT;真"背景= QUOT;白色" ClipToBounds =" True">
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; < / Canvas>
&NBSP; &NBSP; &NBSP; < / ScrollViewer>
< / Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="2" Grid.Column="1"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Canvas x:Name="Pad" Focusable="True" FocusManager.IsFocusScope="True" Width="700" Height="500"
MouseDown="Pad_MouseDown" MouseMove="Pad_MouseMove" MouseUp="Pad_MouseUp"
SnapsToDevicePixels="True" Background="White" ClipToBounds="True">
</Canvas>
</ScrollViewer>
</Grid>
C#
&NBSP; public partial class MainWindow:Window
&NBSP; private bool IsDrawing = false;
&NBSP;私人折线折线;
&NBSP; public MainWindow()
&NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; InitializeComponent();
&NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; private void Pad_MouseDown(object sender,MouseButtonEventArgs e)
&NBSP; &NBSP; &NBSP; if(e.ChangedButton == MouseButton.Left)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; IsDrawing = true;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Point p = e.GetPosition((Canvas)sender);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline = new Polyline();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.Stroke = Brushes.Black ;;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.StrokeThickness = 2;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.StrokeStartLineCap = PenLineCap.Round;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.StrokeEndLineCap = PenLineCap.Round;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.StrokeLineJoin = PenLineJoin.Round;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.Points.Add(p);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.Points.Add(p);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Pad.Children.Add(折线);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; private void Pad_MouseMove(object sender,MouseEventArgs e)
&NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Point p = e.GetPosition((Canvas)sender);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(IsDrawing)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; polyline.Points.Add(p);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; private void Pad_MouseUp(object sender,MouseButtonEventArgs e)
&NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; if(e.ChangedButton == MouseButton.Left&& IsDrawing)
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; IsDrawing = false;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; RenderCanvas();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; &NBSP; &NBSP; }
//渲染画布并将渲染图像设置为画布背景
public static void RenderCanvas()
&NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; ImageBrush brush = new ImageBrush();
&NBSP; &NBSP; &NBSP; RenderTargetBitmap rtb;
&NBSP; &NBSP; &NBSP;矩形边界;
&NBSP; &NBSP; &NBSP; DrawingVisual dv;
$
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; bounds = VisualTreeHelper.GetDescendantBounds(Pad);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; rtb = new RenderTargetBitmap((int)(bounds.Width),(int)(bounds.Height),96,96,PixelFormats.Pbgra32);
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; dv = new DrawingVisual();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP;使用(DrawingContext ctx = dv.RenderOpen())
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; VisualBrush vb = new VisualBrush();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; vb.Stretch = Stretch.None;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; vb.AlignmentX = AlignmentX.Left;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; vb.AlignmentY = AlignmentY.Top;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; vb.Visual = Pad;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; ctx.DrawRectangle(vb,null,new Rect(new Point(),bounds.Size));
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }¥b $ b &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; rtb.Render(dv);
$
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Pad.Children.Clear();
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; brush.Stretch = Stretch.None;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; brush.AlignmentX = AlignmentX.Left;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; brush.AlignmentY = AlignmentY.Top;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; brush.ImageSource = rtb;
&NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Pad.Background =刷子;
&NBSP; &NBSP; &NBSP; }
public partial class MainWindow : Window
private bool IsDrawing = false;
private Polyline polyline;
public MainWindow()
{
InitializeComponent();
}
private void Pad_MouseDown(object sender, MouseButtonEventArgs e)
if (e.ChangedButton == MouseButton.Left)
{
IsDrawing = true;
Point p = e.GetPosition((Canvas)sender);
polyline = new Polyline();
polyline.Stroke = Brushes.Black;;
polyline.StrokeThickness = 2;
polyline.StrokeStartLineCap = PenLineCap.Round;
polyline.StrokeEndLineCap = PenLineCap.Round;
polyline.StrokeLineJoin = PenLineJoin.Round;
polyline.Points.Add(p);
polyline.Points.Add(p);
Pad.Children.Add(polyline);
}
private void Pad_MouseMove(object sender, MouseEventArgs e)
{
Point p = e.GetPosition((Canvas)sender);
if (IsDrawing)
{
polyline.Points.Add(p);
}
}
private void Pad_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left && IsDrawing)
{
IsDrawing = false;
RenderCanvas();
}
}
// Render the Canvas and set the rendered image as background of canvas
public static void RenderCanvas()
{
ImageBrush brush = new ImageBrush();
RenderTargetBitmap rtb;
Rect bounds;
DrawingVisual dv;
bounds = VisualTreeHelper.GetDescendantBounds(Pad);
rtb = new RenderTargetBitmap((int)(bounds.Width), (int)(bounds.Height), 96, 96, PixelFormats.Pbgra32);
dv = new DrawingVisual();
using (DrawingContext ctx = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush();
vb.Stretch = Stretch.None;
vb.AlignmentX = AlignmentX.Left;
vb.AlignmentY = AlignmentY.Top;
vb.Visual = Pad;
ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
Pad.Children.Clear();
brush.Stretch = Stretch.None;
brush.AlignmentX = AlignmentX.Left;
brush.AlignmentY = AlignmentY.Top;
brush.ImageSource = rtb;
Pad.Background = brush;
}
一些屏幕截图不同分辨率700,3000,5000的画布
Nehal Ahmad
Nehal Ahmad
推荐答案
嗨 NehalAhmad,
>>我正在使用画布和渲染制作绘图程序它本身,但每次我使用RenderTargetBitmap渲染时,我的图像变得模糊,更大的画布发生更多。
看起来您使用小笔在大页面上绘图,图像无法清晰,即使如此也能确保分辨率。
您可以尝试以下方法:通过RenderTargetBitmap直接渲染Visual对象。
Hi NehalAhmad,
>>I am making a drawing program using canvas and rendering it on to itself but every time I render using RenderTargetBitmap my image become blurry and it happens more with bigger canvas.
It seems like you use a small pen to draw in the large page, the image cannot be clear even so ensuring the resolution.
You can try the following ways: Render the Visual object directly by RenderTargetBitmap.
<Canvas x:Name="Pad" Focusable="True" FocusManager.IsFocusScope="True" Width="5000" Height="5000"
MouseDown="Pad_MouseDown" MouseMove="Pad_MouseMove" MouseUp="Pad_MouseUp"
SnapsToDevicePixels="True" Background="White" ClipToBounds="True">
</Canvas>
public void RenderCanvas()
{
System.Windows.Media.Imaging.RenderTargetBitmap targetBitmap =
new System.Windows.Media.Imaging.RenderTargetBitmap((int)Pad.RenderSize.Width,
(int)Pad.RenderSize.Height,
96, 96, System.Windows.Media.PixelFormats.Pbgra32);
Pad.Measure(Pad.RenderSize); //Important
Pad.Arrange(new Rect(Pad.RenderSize)); //Important
targetBitmap.Render(Pad);
ImageBrush brush = new ImageBrush();
Pad.Children.Clear();
brush.Stretch = Stretch.None;
brush.AlignmentX = AlignmentX.Left;
brush.AlignmentY = AlignmentY.Top;
brush.ImageSource = targetBitmap;
Pad.Background = brush;
}
这篇关于使用RenderTargetBitmap渲染画布会产生模糊的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!