You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Teams自适应卡片SVG图标无法渲染,求无本地存储转PNG方案

我之前在做Teams Adaptive Cards开发时也碰到过一模一样的问题——Teams对SVG的支持确实很有限,哪怕转成base64嵌入也经常显示undefined。下面给你两个不需要本地存储、完全在内存中把SVG转成PNG的可行方案,亲测有效:

方案1:用SkiaSharp库实现内存转换

SkiaSharp是Google Skia图形引擎的.NET绑定,对SVG的解析和渲染支持很稳定,全程在内存操作,不需要生成本地文件。

步骤1:安装依赖NuGet包

先在项目里安装两个NuGet包:
SkiaSharp 和 SkiaSharp.Svg

步骤2:替换你的转换代码

把原来的SVG转base64的代码替换成下面的逻辑:

using SkiaSharp;
using SkiaSharp.Svg;

// 保留你原来的SVG下载逻辑
byte[] svgBytes;
using (var webClient = new WebClient())
{
    svgBytes = webClient.DownloadData(appSuggestion.IconUri.AbsoluteUri);
}

// 内存中把SVG转成PNG
using (var svg = new SKSvg())
{
    if (svg.Load(new MemoryStream(svgBytes)))
    {
        // 设定目标图片尺寸(和你AdaptiveImage的尺寸一致)
        var targetSize = new SKImageInfo(45, 45);
        using (var surface = SKSurface.Create(targetSize))
        {
            var canvas = surface.Canvas;
            canvas.Clear(SKColors.Transparent); // 保持背景透明

            // 计算缩放比例,确保SVG完整适配目标尺寸
            var scaleX = targetSize.Width / svg.Picture.CullRect.Width;
            var scaleY = targetSize.Height / svg.Picture.CullRect.Height;
            var scale = Math.Min(scaleX, scaleY);
            canvas.Scale(scale);

            // 将SVG绘制到画布上
            canvas.DrawPicture(svg.Picture);

            // 把画布内容转成PNG字节数组,再生成base64 URL
            using (var image = surface.Snapshot())
            using (var pngStream = new MemoryStream())
            {
                image.Encode(SKEncodedImageFormat.Png, 100).SaveTo(pngStream);
                var pngBytes = pngStream.ToArray();
                var pngBase64Uri = new Uri($"data:image/png;base64,{Convert.ToBase64String(pngBytes)}");

                // 构建AdaptiveCard的图片元素(和你原来的逻辑一致,只是换了URL)
                this.Body.Add(new AdaptiveColumnSet
                {
                    Columns = new List<AdaptiveColumn>
                    {
                        new AdaptiveColumn
                        {
                            Items =
                            {
                                new AdaptiveImage
                                {
                                    Url = pngBase64Uri,
                                    PixelWidth = 45,
                                    PixelHeight = 45,
                                },
                            },
                            Width = AdaptiveColumnWidth.Auto,
                        },
                    }
                });
            }
        }
    }
}

方案2:用ImageSharp库实现内存转换

ImageSharp是另一个跨平台的.NET图形库,API更简洁,同样支持内存中SVG转PNG。

步骤1:安装依赖NuGet包

安装三个NuGet包:
SixLabors.ImageSharp、SixLabors.ImageSharp.Drawing 和 SixLabors.ImageSharp.Formats.Svg

步骤2:实现转换代码

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Svg;
using SixLabors.ImageSharp.Processing;

// 保留原SVG下载逻辑
byte[] svgBytes;
using (var webClient = new WebClient())
{
    svgBytes = webClient.DownloadData(appSuggestion.IconUri.AbsoluteUri);
}

// 内存转换SVG到PNG
using (var svgStream = new MemoryStream(svgBytes))
using (var image = Image.Load(svgStream, new SvgDecoder()))
{
    // 调整图片尺寸到目标大小,保持比例
    image.Mutate(x => x.Resize(new ResizeOptions
    {
        Size = new Size(45, 45),
        Mode = ResizeMode.Max
    }));

    // 转成PNG字节数组并生成base64 URL
    using (var pngStream = new MemoryStream())
    {
        image.Save(pngStream, new PngEncoder());
        var pngBytes = pngStream.ToArray();
        var pngBase64Uri = new Uri($"data:image/png;base64,{Convert.ToBase64String(pngBytes)}");

        // 添加到AdaptiveCard中
        this.Body.Add(new AdaptiveColumnSet
        {
            Columns = new List<AdaptiveColumn>
            {
                new AdaptiveColumn
                {
                    Items =
                    {
                        new AdaptiveImage
                        {
                            Url = pngBase64Uri,
                            PixelWidth = 45,
                            PixelHeight = 45,
                        },
                    },
                    Width = AdaptiveColumnWidth.Auto,
                },
            }
        });
    }
}

额外注意事项

  • 确保NuGet包版本和你的项目.NET版本兼容,比如.NET Framework和.NET Core/.NET 5+的包版本可能略有差异
  • 如果你的SVG包含外部资源(比如自定义字体),需要额外处理资源加载,但大多数图标类SVG都是独立的,不会有这个问题
  • Teams Adaptive Cards对base64格式的PNG支持非常稳定,用这个方法替换后应该不会再出现undefined的问题

内容的提问来源于stack exchange,提问作者Rex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 10:22:41