本文记录 Avalonia 的一个已知问题,使用 RenderTargetBitmap 进行截图时,如果顶层子控件没有设置背景色或背景色是透明色,则截图保存出来的图片里面的文本字符串都是模糊的
此问题能够在 Avalonia 的 11.0-11.3.2 版本复现,更低版本我就没有测试了
出现问题的表现的截图界面图片的文本模糊如下图所示
在 Avalonia 里,使用 RenderTargetBitmap 对控件进行截图,如果控件的顶层子控件没有背景色,则会截图出一张文本是模糊的图片。如果给控件的顶层子控件设置白色作为背景色,则能够截图出正常渲染的清晰文本
此问题已报告给官方,详细请看 https://github.com/AvaloniaUI/Avalonia/issues/19229
现步骤如下:
- 创建一个空的 Avalonia 程序,在 MainView.axaml 里面放入一个包含“Hello World”内容的 TextBlock 控件,以及两个按钮。两个按钮分别是 TakeSnapshotButton 和 TakeSnapshotWithFixButton 按钮
- 设置 TakeSnapshotButton 按钮在点击的时候,使用 RenderTargetBitmap 进行截图,且将图片保存到 1.png 文件里
- 设置 TakeSnapshotWithFixButton 按钮在点击的时候,先设置 RootGrid 的背景色为白色,然后再使用 RenderTargetBitmap 进行截图,且将图片保存到 2.png 文件里
其代码内容如下:
MainView.axaml:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:bunaylenerkeLailurlairfea="clr-namespace:KarhelearkuDemkunalhaw"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="KarhelearkuDemkunalhaw.Views.MainView">
<Grid x:Name="RootGrid">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Hello World"></TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,300,10,10">
<Button x:Name="TakeSnapshotButton" Click="TakeSnapshotButton_OnClick"
ToolTip.Tip="Take Snapshot to 1.png file. And you can find the blur text.">Take Snapshot</Button>
<Button x:Name="TakeSnapshotWithFixButton" Margin="10,0,10,0" Click="TakeSnapshotWithFixButton_OnClick"
ToolTip.Tip="Take Snapshot to 2.png file. And you can find the clear text.">Take Snapshot with fix</Button>
</StackPanel>
</Grid>
</UserControl>
MainView.axaml.cs:
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Styling;
using System;
using System.IO;
using Avalonia;
using Avalonia.Interactivity;
using Avalonia.Media.Imaging;
using Avalonia.Threading;
namespace KarhelearkuDemkunalhaw.Views;
public partial class MainView : UserControl
{
public MainView()
{
InitializeComponent();
}
private void TakeSnapshotButton_OnClick(object? sender, RoutedEventArgs e)
{
var mainView = this;
var renderTargetBitmap =
new RenderTargetBitmap(new PixelSize((int) mainView.Bounds.Width, (int) mainView.Bounds.Height), new Vector(96, 96));
renderTargetBitmap.Render(mainView);
var file = Path.Join(AppContext.BaseDirectory, "1.png");
renderTargetBitmap.Save(file, 100);
}
private void TakeSnapshotWithFixButton_OnClick(object? sender, RoutedEventArgs e)
{
RootGrid.Background = Brushes.White;
Dispatcher.UIThread.InvokeAsync(() =>
{
var mainView = this;
var renderTargetBitmap =
new RenderTargetBitmap(new PixelSize((int) mainView.Bounds.Width, (int) mainView.Bounds.Height), new Vector(96, 96));
renderTargetBitmap.Render(mainView);
var file = Path.Join(AppContext.BaseDirectory, "2.png");
renderTargetBitmap.Save(file, 100);
// 截图完成,重新设置到透明色。下次使用 TakeSnapshotButton 按钮截图时,依然文本模糊
RootGrid.Background = Brushes.Transparent;
});
}
}
请运行项目,依次点击 TakeSnapshotButton 和 TakeSnapshotWithFixButton 按钮,观察程序生成的 1.png 和 2.png 文件
你可以看见 1.png 里面的文本都是模糊的,如上图所示
而 2.png 里面的文本是清晰的,如下图所示。证明了只要给 RootGrid 设置非透明的背景色,则能够让渲染正常工作
本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 86ff9a4bb65e2775fb71d34f34283b68b5ab1605
以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 86ff9a4bb65e2775fb71d34f34283b68b5ab1605
获取代码之后,进入 AvaloniaIDemo/KarhelearkuDemkunalhaw 文件夹,即可获取到源代码
更多技术博客,请参阅 博客导航
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/Avalonia-%E5%B7%B2%E7%9F%A5%E9%97%AE%E9%A2%98-%E4%BD%BF%E7%94%A8-RenderTargetBitmap-%E6%88%AA%E5%9B%BE%E6%96%87%E6%9C%AC%E6%A8%A1%E7%B3%8A.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航
本作品采用
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:
https://blog.lindexi.com
),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请
与我联系
。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利