我之前不是用 Avalonia 开发了 StarBlogPublisher(一款为 StarBlog 设计的 Markdown 文章发布工具)吗?
当时里面有个分类 词云(Word Cloud) 展示功能。 初版的词云虽然 "能用",但效果极其粗糙——基本只是简单堆叠文字,完全没有体现出词云那种灵动、密集、错落有致的美感。
于是,我决定 彻底重构 这一模块,重新寻找合适的词云生成方案。
在 Avalonia 生态中是没有直接可用的词云组件的。
不过没事,C# 的生态还算丰富,基本要啥有啥,词云自然不在话下。
在调研阶段,我找到了两个比较流行的 C# 词云库:
简单对比一下:
特性 | Sdcb.WordCloud | KnowledgePicker.WordCloud |
---|---|---|
渲染引擎 | SkiaSharp(跨平台) | SkiaSharp(跨平台) |
输出格式 | 图片(PNG)、SVG、JSON | 图片(Bitmap)、SVG(需要自绘) |
自定义程度 | 高(遮罩、字体、多方向、JSON输出等) | 中(字体、颜色、布局可定制,但不支持遮罩) |
遮罩功能 | ✅ 原生支持遮罩图生成特定形状词云 | ❌ 暂不支持遮罩,生成规则矩形词云 |
最近维护状态 | 活跃(2024年持续更新) | 活跃(2024年有提交) |
使用复杂度 | 中(配置多、自由度高) | 中(较简洁,适合快速集成) |
SkiaSharp
,意味着可以在 Windows、Linux、macOS 等多平台运行。最终,我选择了功能更强大、兼容性更好的 Sdcb.WordCloud。
Sdcb.WordCloud 是一个基于 SkiaSharp
的跨平台词云生成库,具备以下特点:
dotnet add package Sdcb.WordCloud
重构后的词云生成逻辑主要分为两步:
首先,从后端API请求分类词频数据,并进行简单扩充(让词云密度更高)。
private async Task<List<WordScore>?> GetWordScores() {
var response = await ApiService.Instance.Categories.GetWordCloud();
if (response.Data == null) thrownew Exception("获取词云数据失败");
var originalScores = response.Data
.Select(e => new WordScore(Score: e.Value, Word: e.Name))
.ToList();
var extendedScores = new List<WordScore>();
foreach (var score in originalScores) {
for (int i = 0; i < 10; i++) {
extendedScores.Add(score);
}
}
return extendedScores;
}
这里小技巧: 👉 将原本每个单词的词频复制多次,可以有效提升词云的视觉密度和丰富度。
拿到词频数据后,使用 WordCloud.Create()
创建词云对象,并通过遮罩图案和字体定制,生成最终的词云图片。
private async Task GenerateWordCloudImage() {
var wordScores = await GetWordScores();
if (wordScores == null || !wordScores.Any()) {
ErrorMessage = "没有可用的词云数据";
return;
}
var wc = WordCloud.Create(new WordCloudOptions(900, 900, wordScores) {
FontManager = new FontManager([
SKTypeface.FromFamilyName("Times New Roman")
]),
Mask = MaskOptions.CreateWithForegroundColor(
SKBitmap.Decode(awaitnew HttpClient().GetByteArrayAsync(
"https://io.starworks.cc:88/cv-public/2024/alice_mask.png"
)),
SKColors.White
)
});
usingvar skImage = wc.ToSKBitmap();
usingvar data = skImage.Encode(SKEncodedImageFormat.Png, 100);
usingvar stream = new MemoryStream(data.ToArray());
WordCloudImage = new Bitmap(stream);
}
这里用了两点增强体验的小技巧:
话说之前的效果能算词云吗??
通过这次重构,我总结出几点经验:
如果你也在C#项目中需要集成词云功能,推荐试试Sdcb.WordCloud
—— 简单高效,而且效果不错
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有