序
一天,作者在深圳湾吹风时突然想到自己还有 20 多位粉丝,所以决定每周至少要水一篇文章。
众所周知,一篇文章要有封面,正痛苦时,.NET 官方网站更新了一大波质量上乘的插图;高兴之余,发觉平台不支持 SVG 图片,所以有了这篇文章。
不过在这里,我劝!各位年轻人,耗自为汁,不要再耍这种聪明,小聪明,啊!互联网还是要讲版权,不要搞窝里斗。
介绍
首先进行简单介绍,若已有了解可跳过该小节。
SVG 是一种基于 XML 语法的图像格式,全称是可缩放矢量图(Scalable Vector Graphics)。其他图像格式都是基于像素处理的,SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。
阮一峰的网络日志《SVG 图像入门教程》http://www.ruanyifeng.com/blog/2018/08/svg.html
PNG 是一种采用从 LZ77 派生的无损数据压缩算法的位图格式,其压缩比高,生成文件体积小。
百度百科《PNG》https://baike.baidu.com/item/png
稍微总结,SVG 文本体积小、缩放不失真,PNG无损、压缩比高、背景透明,需要详细了解请打开上面的链接进行学习。
SVG.NET
微软开源网站上有一个 SVG 项目(svg.codeplex.com),但是因为年代久远长时间没有维护,并且没有发布 Nuget 包;后来有组织将代码维护到了 GitHub(github.com/vvvv/SVG),沿用了微软的协议(MS-PL),并且发布了 Nuget 包,使用非常简单:
PM> Install-Package Svg
var svg = SvgDocument.Open("dotnet.svg");
Bitmap image = svg.Draw();
image.Save("dotnet.png");
上述代码中,调用 Draw 方法绘制图片时没有设置宽高,所以会使用 SVG 文档中默认的宽高,这样转换出来的图片分辨率可能会略低,可以按照原有比例进行放大:
var svg = SvgDocument.Open("dotnet.svg");float width = svg.ViewBox.Width * 4;
float height = svg.ViewBox.Height * 4;Bitmap image = svg.Draw((int)width, (int)height);
image.Save("dotnet.png");
顺便提一下,该包以及其依赖包会涉及到多种开源协议:MIT、MS-PL、LGPL;主要说明一下 MS-PL 和 LGPL,都可以作为类库引用到商业软件中。
到此,SVG 转换为 PNG 已经完成,如果需要继续了解 .NET 工具包制作请继续往下。
工具包制作
.NET Core 工具是一种特殊的 NuGet 包,其中包含控制台应用程序。
微软官方文档《管理工具》https://aka.ms/global-tools
即可以通过命令 dotnet tool 进行工具的安装/卸载/管理,详情请阅读官方教程。
首先,我们选择一个包来简化程序参数解析等处理过程:
PM> Install-Package McMaster.Extensions.CommandLineUtils
该程序也是之前一直在微软内部作为共享代码使用,然后作为 extensions 产品的一部分发布成了 Nuget 包,但是后来放弃并邀请社区维护;社区接力后,添加了很多诸如依赖注入等有趣的功能,现微软推荐大家使用该社区维护版本。深度使用请阅读其 GitHub 上的 Readme。
首先我们定义需要接收的数据,SVG 目录、PNG 目录、放大倍数:
internal interface IOptions
{public string SvgDir { get; set; }public string PngDir { get; set; }public int Enlarge { get; set; }
}
然后编写 Command 类,CommandLineUtils 会根据该类生成帮助文档,以及接收并处理用户输入:
internal class Command : IOptions
{[Option(Description = "SVG 图片目录")]public string SvgDir { get; set; }[Option(Description = "PNG 图片目录")]public string PngDir { get; set; }[Option(Description = "放大倍数")]public int Enlarge { get; set; }public void OnExecute(){Handler handler = new(){Options = this,};handler.Handle();}
}
最后在 Program.cs 中将 CommandLineUtils 对接到程序入口:
using McMaster.Extensions.CommandLineUtils;CommandLineApplication.Execute<Command>(args);
至此,该工具的主要流程已完成,但是要真正运行还需要编写 Command 中调用的 Handler 类,该类主要逻辑是将 SVG 转为 PNG,上述章节已有讲解;其整个类还有其他文件操作、异常处理代码,全部列出会占用较多篇幅,不想动手的同学可以直接点击文章尾部的 原文链接 到 GitHub 下载源代码。
最后,制作工具包还需要在项目文件中配置:
<PackAsTool>true</PackAsTool>
<ToolCommandName>svg2png</ToolCommandName>
将编译生成的 Nuget 包发布到 nuget.org 中,过程略。
使用 svg2png
安装 svg2png
PS> dotnet tool install -g svg2png
查看帮助
PS> svg2png -h
Usage: svg2png [options]Options:-s|--svg-dir <SVG_DIR> SVG 图片目录-p|--png-dir <PNG_DIR> PNG 图片目录-e|--enlarge <ENLARGE> 放大倍数-?|-h|--help Show help information
转换
PS> svg2png -s E:\svg2png -p E:\output -e 4
END
祝编码愉快。