Avalonia 渲染svg文件
Xaml部分代码
<ScrollViewer Grid.Row="3" Padding="0 0 -16 0" VerticalScrollBarVisibility="Auto"
Background="{Binding Vo.MuteTotal, Converter={StaticResource DataBg},
ConverterParameter=#ffffff|avares://xxxx.Pc.Desktop/Assets/Chat/Group/empty_mute_member.svg}">
Avalonia版本小于等于11.3.2
public class DataBackgroundConverter: MarkupExtension, IValueConverter {
private static DataBackgroundConverter ? _instance;
public override object ProvideValue(IServiceProvider serviceProvider) => _instance ??= new();
public object ? Convert(object ? value, Type targetType, object ? parameter, CultureInfo culture) {
// 参数格式:Color|ImagePath
var param = parameter as string;
if (string.IsNullOrEmpty(param))
return new SolidColorBrush(Colors.Transparent);
var parts = param.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
return new SolidColorBrush(Colors.Transparent);
var colorHex = parts[0].Trim();
var imageAsset = parts[1].Trim();
bool hasData = false;
if (value is null) {
hasData = false;
} else if (value is int total) {
hasData = total > 0;
} else if (value is IEnumerable collection) {
// 尝试判断集合是否为空
var enumerator = collection.GetEnumerator();
hasData = enumerator.MoveNext(); // 只要能 MoveNext 就说明有元素
} else {
// 非集合对象:只要不为 null 就算有数据
hasData = true;
}
if (hasData) {
// ✅ 有数据:返回颜色
if (Color.TryParse(colorHex, out
var color)) {
return new SolidColorBrush(color);
}
return new SolidColorBrush(Colors.White);
} else {
// ❌ 无数据:返回背景图
try {
if (imageAsset.EndsWith("svg")) {
return LoadSvgAsBrush(imageAsset);
}
var stream = AssetLoader.Open(new Uri(imageAsset));
var bitmap = new Bitmap(stream);
return new ImageBrush(bitmap) {
Stretch = Stretch.Uniform, AlignmentX = AlignmentX.Center, AlignmentY = AlignmentY.Center,
};
} catch (Exception ex) {
System.Diagnostics.Debug.WriteLine($ "加载背景图失败: {ex.Message}");
}
return new SolidColorBrush(Colors.LightGray);
}
}
public static ImageBrush LoadSvgAsBrush(string assetPath, PixelSize ? pixelSize = null) {
// 1. 加载 SVG
var svgSource = SvgSource.Load(assetPath);
var svgImage = new SvgImage {
Source = svgSource
};
// 2. 渲染目标像素大小
var size = pixelSize ?? new PixelSize(800, 800);
var rtb = new RenderTargetBitmap(size);
using(var ctx = rtb.CreateDrawingContext(false)) // ⚡ 注意这里传 false
{
// 目标矩形(以像素为单位)
var destRect = new Rect(0, 0, size.Width, size.Height);
// 源矩形(SVG 原始大小,如果没有,就用目标大小)
var srcSize = svgImage.Size;
var srcRect = new Rect(0, 0, srcSize.Width, srcSize.Height);
// 绘制 SVG -> 位图
ctx.DrawImage((IImage) svgImage, srcRect, destRect);
}
// 3. 返回 ImageBrush
return new ImageBrush(rtb);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotSupportedException("不支持反向转换");
}
}
Avalonia版本大于等于11.3.6
使用Svg.Controls.Skia.Avalonia,版本11.3.6.2
地址为:https://libraries.io/nuget/Svg.Controls.Skia.Avalonia/11.3.6.2
public class DataBackgroundConverter: MarkupExtension, IValueConverter {
private static DataBackgroundConverter ? _instance;
public override object ProvideValue(IServiceProvider serviceProvider) => _instance ??= new();
public object ? Convert(object ? value, Type targetType, object ? parameter, CultureInfo culture) {
// 参数格式:Color|ImagePath
var param = parameter as string;
if (string.IsNullOrEmpty(param))
return new SolidColorBrush(Colors.Transparent);
var parts = param.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
return new SolidColorBrush(Colors.Transparent);
var colorHex = parts[0].Trim();
var imageAsset = parts[1].Trim();
bool hasData = false;
if (value is null) {
hasData = false;
} else if (value is int total) {
hasData = total > 0;
} else if (value is IEnumerable collection) {
// 尝试判断集合是否为空
var enumerator = collection.GetEnumerator();
hasData = enumerator.MoveNext(); // 只要能 MoveNext 就说明有元素
} else {
// 非集合对象:只要不为 null 就算有数据
hasData = true;
}
if (hasData) {
// ✅ 有数据:返回颜色
if (Color.TryParse(colorHex, out
var color)) {
return new SolidColorBrush(color);
}
return new SolidColorBrush(Colors.White);
} else {
// ❌ 无数据:返回背景图
try {
if (imageAsset.EndsWith("svg")) {
// // var fromPath = SvgResourceExtension.CreateBrush(
// // "avares://MyAssembly/Assets/Icon.svg",
// // stretch: Stretch.Fill,
// // alignmentX: AlignmentX.Right,
// // alignmentY: AlignmentY.Bottom);
return SvgResourceExtension.CreateBrush(
imageAsset,
stretch: Stretch.Uniform,
alignmentX: AlignmentX.Center,
alignmentY: AlignmentY.Center);
}
var stream = AssetLoader.Open(new Uri(imageAsset));
var bitmap = new Bitmap(stream);
return new ImageBrush(bitmap) {
Stretch = Stretch.Uniform, AlignmentX = AlignmentX.Center, AlignmentY = AlignmentY.Center,
};
} catch (Exception ex) {
System.Diagnostics.Debug.WriteLine($ "加载背景图失败: {ex.Message}");
}
return new SolidColorBrush(Colors.LightGray);
}
}
public static ImageBrush LoadSvgAsBrush(string assetPath, PixelSize ? pixelSize = null) {
// 1. 加载 SVG
var svgSource = SvgSource.Load(assetPath);
var svgImage = new SvgImage {
Source = svgSource
};
// 2. 渲染目标像素大小
var size = pixelSize ?? new PixelSize(800, 800);
var rtb = new RenderTargetBitmap(size);
using(var ctx = rtb.CreateDrawingContext(false)) // ⚡ 注意这里传 false
{
// 目标矩形(以像素为单位)
var destRect = new Rect(0, 0, size.Width, size.Height);
// 源矩形(SVG 原始大小,如果没有,就用目标大小)
var srcSize = svgImage.Size;
var srcRect = new Rect(0, 0, srcSize.Width, srcSize.Height);
// 绘制 SVG -> 位图
ctx.DrawImage((IImage) svgImage, srcRect, destRect);
}
// 3. 返回 ImageBrush
return new ImageBrush(rtb);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotSupportedException("不支持反向转换");
}
}
xmlns:skia="using:Avalonia.Svg.Skia"
<skia:Svg Path="avares://Resources/Assets/Workspace/Gear.svg"/>

浙公网安备 33010602011771号