Svg转Jpg
Svg转Jpg
需求描述
在C#中将 Svg 转换成 Jpg 图片。
转出来的图片,存在部分文字偏移走开的现象。
通过找到相应位置,调整偏移,解决问题。
关键在于,匹配到 hanging、baseline、rotate 的关键字,修改偏移位置实现。
实现的代码
public void svgToPng()
{
// 导出图件
int picWidth = 300, picHeight = 200, dpi = 50;
var svgFile = @".\output\svg.svg";
var svgLine = File.ReadAllLines(svgFile);
var svgContent = "";
var keyHanging = "<text dominant-baseline=\"hanging\"";
var keyRotate = "rotate(-90)";
var keyBaseline = "<text dominant-baseline=\"baseline\"";
for (var i = 0; i < svgLine.Count(); i++)
{
var line = svgLine[i];
if (line.IndexOf(keyHanging) >= 0 )
{
line = processText(line);
}
if (line.IndexOf(keyRotate) >= 0)
{
line = processText(line);
}
if (line.IndexOf(keyBaseline) >= 0)
{
line = processText(line);
}
svgContent += line;
}
var svg = SvgDocument.FromSvg<SvgDocument>(svgContent);
// 导出到 jpg
var jpgpath = @".\output\jpg2.jpg";
int nNewWidth = picWidth * 4;
int nNewHeight = picHeight * 4;
Bitmap bitmapJpg = svg.Draw(nNewWidth, nNewHeight);
bitmapJpg.Save(jpgpath, System.Drawing.Imaging.ImageFormat.Jpeg);
}
public string processText(string line)
{
var keyHanging = "<text dominant-baseline=\"hanging\"";
var keyRotate = "rotate(-90)";
var keyBaseline = "<text dominant-baseline=\"baseline\"";
var pattern = @"translate\(([^\)]+)\)";
var patternFontSize = @"font-size=""(\d+\.?\d*)""";
var match = Regex.Matches(line, pattern);
if (match.Count > 0)
{
var result = match[0].Value;
var m = match[0];
var groups = m.Groups;
var beforeText = groups[1].ToString();
string[] arrItem = beforeText.Split(new[] { ',' });
var x = Convert.ToDouble(arrItem[0]);
var y = Convert.ToDouble(arrItem[1]);
var matchFontSize = Regex.Matches(line, patternFontSize);
var fontSizeText = matchFontSize[0].Groups[1].Value;
var fontSize = Convert.ToDouble(fontSizeText);
if (line.IndexOf(keyRotate) >= 0)
{
if (x < 50)
{
x += 15;
}
else
{
x -= 12;
}
}
else if (line.IndexOf(keyHanging) >= 0)
{
if (fontSize > 10)
{
// 加上偏移
y += 12;
}
else
{
y += 6;
}
}
else if (line.IndexOf(keyBaseline) >= 0)
{
y -= 10;
}
var afterText = x + "," + y;
line = line.Replace(beforeText, afterText);
}
return line;
}