使用SVG-Net将SVG转PNG/JPG时字体不加载问题求助
解决SVG-Net在Azure Functions中转换SVG为位图时的字体渲染问题
核心问题分析
你遇到的问题本质是:
- 本地环境通过安装字体让SVG-Net能识别,但Azure Functions(PaaS)不允许安装系统字体
- 嵌入base64的
@font-face在SVG浏览器中生效,但SVG-Net的渲染引擎未正确解析加载
可行解决方案
方案1:手动加载字体文件到内存(推荐,稳定可靠)
Azure Functions允许你将字体文件打包到项目中,无需安装到系统,直接在代码中加载:
准备字体文件
- 将你的TTF字体文件(如
SegoeProBold.ttf)添加到Azure Functions项目 - 在文件属性中设置复制到输出目录为「如果较新则复制」
- 将你的TTF字体文件(如
代码中加载并注册字体
修改你的转换代码,添加字体加载逻辑:using System.Drawing.Text; using System.IO; // 加载自定义字体到私有字体集合 var privateFonts = new PrivateFontCollection(); var fontPath = Path.Combine(Environment.GetEnvironmentVariable("HOME") ?? Environment.CurrentDirectory, "SegoeProBold.ttf"); privateFonts.AddFontFile(fontPath); // 确保SVG中的文本元素使用的font-family与加载的字体名称完全一致 svgContent = svgContent.Replace("font-family:Segoe Pro Bold", "font-family:\"Segoe Pro Bold\""); // 后续的SVG解析和转换代码保持不变 var mySvg = SvgDocument.FromSvg<SvgDocument>(svgContent); mySvg.Height = new SvgUnit(SvgUnitType.Pixel, pixelHeight); mySvg.Width = new SvgUnit(SvgUnitType.Pixel, pixelWidth); mySvg.ViewBox = new SvgViewBox(0, 0, viewBoxWidth, viewBoxHeight); Bitmap bmpSquare = mySvg.Draw(pixelWidth, pixelHeight); bmpSquare.Save(FilePathJPG, jgpEncoder, myEncoderParameters); bmpSquare.Save(FilePathPNG, pngEncoder, myEncoderParameters);
方案2:修正SVG的base64字体嵌入写法
如果坚持用嵌入字体,需确保SVG的@font-face写法完全符合SVG-Net的解析要求:
<defs> <style type="text/css"> @font-face { font-family: "Segoe Pro Bold"; /* 名称带空格必须加引号 */ src: url("data:font/truetype;base64,[你的完整base64编码内容]") format("truetype"); font-weight: bold; font-style: normal; } </style> </defs> <!-- 文本元素必须明确引用字体 --> <text x="20" y="60" font-family="Segoe Pro Bold" font-size="32" fill="#000">测试渲染文本</text>
注意:
- 不要在data URL中添加
charset=utf-8(部分渲染引擎不兼容) - 确保base64编码没有换行或多余空格
- 文本元素的
font-family必须与@font-face中的名称完全匹配(包括引号)
方案3:切换到SkiaSharp后端的SVG-Net分支
SVG-Net有基于SkiaSharp的分支(Svg.Skia),对字体解析支持更好,尤其是嵌入字体场景:
- 安装NuGet包
Svg.Skia - 修改转换代码为SkiaSharp版本:
using Svg.Skia; using SkiaSharp; var svg = new SKSvg(); svg.Load(new MemoryStream(Encoding.UTF8.GetBytes(svgContent))); using var bitmap = new SKBitmap(pixelWidth, pixelHeight); using var canvas = new SKCanvas(bitmap); canvas.Clear(SKColors.White); canvas.DrawPicture(svg.Picture); using var image = SKImage.FromBitmap(bitmap); using var data = image.Encode(SKEncodedImageFormat.Png, 100); using var stream = File.OpenWrite(FilePathPNG); data.SaveTo(stream);
SkiaSharp对嵌入式字体的支持更完善,且在Azure Functions中无需额外配置。
关键注意事项
- Azure Functions Windows环境支持System.Drawing,但Linux环境需安装
libgdiplus(推荐用Windows环境避免麻烦) - 字体名称必须完全匹配,包括大小写和空格(比如
Segoe Pro Bold不能写成SegoeProBold)
内容的提问来源于stack exchange,提问作者Abhilab Das
相关产品推荐
相关产品推荐

