65.9K
CodeProject 正在变化。 阅读更多。
Home

SharpVectors - SVG# Reloaded:简介

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (32投票s)

2010年11月16日

BSD

10分钟阅读

viewsIcon

218265

downloadIcon

21848

一个将 SVG 转换为 WPF 并将在 WPF 应用程序中查看 SVG 文件的 C# 库。

SharpVectors 1.0 Beta

引言

SVG# Reloaded 项目旨在提供库和工具,用于在 Windows 上,尤其是在 Windows Presentation Foundation 平台上,解析、转换和查看 SVG。

背景

几个月前,我正在寻找一个库,用于将 SVG 图表转换为 XAML,以便在 WPF 应用程序中使用。我最初以为一些可用的开源项目可以轻松处理该项目,但都失败了。下一步是寻找一个商业库,唯一找到的那个也未能处理该项目,所以我别无选择,只能自己创建一个,因为我已经告诉我的老板这应该不是问题。

我从 SharpVectorGraphics (又名 SVG#) 开始,因此得名 SVG# Reloaded。

项目信息

该项目目前托管在 Codeplex

SharpVectors 1.0 目前处于 Beta 阶段,以便有更多时间进行文档编写、修复错误和接受建议。最终版本计划于 2011 年 1 月发布。

SVG 到 XAML/WPF 的转换已经足够完善,我已经在实际应用中使用了它。

快速入门

SVG# Reloaded 封装在几个 .NET 程序集中。库本身分为两部分:数据处理(解析和建模)和渲染。这使得拥有不同的渲染引擎成为可能,目前我们有基于 WPF 的渲染引擎和基于 GDI+ 的渲染引擎(对原始 SVG# 渲染的改进,但与 WPF 渲染引擎相比不够完善)。

WPF 包

对于 WPF 包,这是依赖关系图

SharpVectors.Converters.png

  • SharpVectors.Core:这是核心库,定义了 W3C SVG 规范定义的所有必需接口,包括事件和样式表接口。
  • SharpVectors.Dom:这是 .NET Framework XML DOM (XmlDocument) 实现的扩展,用于支持 SVG。
  • SharpVectors.Css:这是 .NET Framework DOM 的扩展,用于支持样式表接口。
  • SharpVectors.Model:这是 SVG DOM 和接口的主要实现。这是 SVG 文档的解析器,将 SVG 文件转换为 .NET 对象的内存模型。此程序集和上述程序集不依赖于 GDI+ 或 WPF 库。
  • SharpVectors.Runtime:这是一个可选的 WPF 库,在运行时提供 SVG 对象特定的信息。这包括用于处理 GlyphTypeface.FontUri 的转换类,否则它将被硬编码为可能无法在用户机器上工作的完整路径信息,以及用于处理嵌入图像等的类。
  • SharpVectors.Rendering.Wpf:这是 WPF 库,它处理 SVG 对象到 WPF 绘图对象的渲染。
  • SharpVectors.Converters:这是 WPF 库,它使用 SharpVectors.Rendering.Wpf 库执行实际的转换以供查看。

注意:当前的 WPF 包只生成低级对象;GeometryDrawing。不生成 Shape 等更高级别的对象,因此不支持 Silverlight。

GDI+ 包

依赖关系图如下所示

SharpVectorsGdi.png
  • SharpVectors.Rendering.Gdi:这是 GDI+ 库,它处理 SVG 对象到 System.Drawing 对象的渲染。

Using the Code

在本节中,我们将提供一些示例来演示此库的使用。

这些示例代码分为两部分;转换器和控件(包括标记扩展)。这些部分的完整 VS.NET 解决方案可供下载,这里是使用这些项目/解决方案的一些指导

转换器示例:SharpVectorsSamples

  1. 这些是用于教程的 SVG 到 WPF 转换器示例,总共有 8 个简单项目(C# 和 VB.NET)
  2. 为了使项目中的当前程序集引用自动解析,请将这些示例解压到以下目录
    SharpVectorsReloaded\Samples\SharpVectorsSamples

标记扩展和控件示例:SharpVectorsControlSamples

  1. 这些是用于教程的标记扩展和控件示例,总共有 6 个项目。
  2. 为了使项目中的当前程序集引用自动解析,请将这些示例解压到以下目录
    SharpVectorsReloaded\Samples\SharpVectorsControlSamples

转换器:概述

SVG 到 WPF 转换是当前此 SVG# Reloaded 库的主要用途。其他用途将随着时间的推移而改进。

下图显示了所有可用的转换器。

Converters.png
  • FileSvgConverter:这将 SVG 文件转换为相应的 XAML 文件,可在 WPF 应用程序中查看。转换后文件中的根对象是 DrawingGroup
  • FileSvgReader:这将 SVG 文件转换为 DrawingGroup,并且可以选择将结果保存到文件中作为 XAML。
  • ImageSvgConverter:这将 SVG 文件转换为静态或位图图像,可保存到文件中。
  • DirectorySvgConverter:这将 SVG 文件目录(并可选地包括子目录)转换为指定目录中的 XAML 文件,同时保持原始目录结构。

现在,基类 SvgConverter 定义了以下通用属性

SvgConverter.png
  • DrawingSettings:这由 SharpVectors.Rendering.Wpf 程序集中的 WpfDrawingSettings 类定义,并提供了可用于转换的绘图/渲染选项。

    DrawingSettings.png

    此类的所有属性都已详细文档化。最重要的属性是

    • CultureInfo:这是用于文本渲染的文化信息,并传递给 FormattedText 类。默认值是英语文化。
    • IncludeRuntime:这决定了使用转换输出的应用程序是否会链接到 SharpVectors.Runtime.dll。默认值是 true,如果您不打算使用运行时程序集,请将其设置为 false
    • TextAsGeometry:这决定了文本是否渲染为路径几何。默认值是 false。垂直文本目前不支持此选项。如果您不想使用运行时程序集,请将此设置为 true,这样字体路径就不会包含在输出中。
  • SaveXaml:确定是否将转换输出保存为 XAML 格式。
  • SaveZaml:确定是否将转换输出保存为 ZAML 格式,这是 XAML 格式的 G-zip 压缩,类似于 SVGZ(对于 SVG)。
  • UseFrameXamlWriter:确定在将输出保存为 XAML 格式时是否使用 .NET Framework 版本的 XAML 写入器。默认值是 false,并使用自定义的 XAML 写入器。

转换器:示例

我们将创建一个简单的控制台应用程序进行说明,使用以下 SVG 示例文件(命名为 Test.svg

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="6cm" height="5cm" viewBox="0 0 600 500"
xmlns="http://www.w3.org/2000/svg" version="1.1">
    <!-- Outline the drawing area with a blue line -->
    <rect x="1" y="1" width="598" height="498" 
          fill="none" stroke="blue"/>
    <circle cx="300" cy="225" r="100" fill="red"/>
    <text x="300" y="480" font-family="Verdana" 
          font-size="35" text-anchor="middle">
        Sample Text 1
    </text>
</svg>
  1. 创建一个控制台 .NET 3.5 框架应用程序,命名为 FileSvgConverterSample
  2. 添加以下 WPF 框架程序集
    • WindowBase.dll
    • PresentationCore.dll
    • PresentationFramework.dll
  3. 添加以下 SVG# Reloaded 程序集
    • SharpVectors.Converters.dll
    • SharpVectors.Core.dll
    • SharpVectors.Css.dll
    • SharpVectors.Dom.dll
    • SharpVectors.Model.dll
    • SharpVectors.Rendering.Wpf.dll
    • SharpVectors.Runtime.dll
  4. 将生成的代码修改为以下内容

    对于 C# 应用程序

    using System;
    
    using SharpVectors.Converters;
    using SharpVectors.Renderers.Wpf;
    
    namespace FileSvgConverterSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 1. Create conversion options
                WpfDrawingSettings settings = new WpfDrawingSettings();
                settings.IncludeRuntime = false;
                settings.TextAsGeometry = true;
    
                // 2. Select a file to be converted
                string svgTestFile = "Test.svg";
    
                // 3. Create a file converter
                FileSvgConverter converter = new FileSvgConverter(settings);
                // 4. Perform the conversion to XAML
                converter.Convert(svgTestFile);
            }
        }
    }

    对于 VB.NET 应用程序

    Imports SharpVectors.Converters
    Imports SharpVectors.Renderers.Wpf
    
    Module MainModule
    
        Sub Main()
            ' 1. Create conversion options
            Dim settings As WpfDrawingSettings = New WpfDrawingSettings()
            settings.IncludeRuntime = False
            settings.TextAsGeometry = True
    
            ' 2. Select a file to be converted
            Dim svgTestFile As String = "Test.svg"
    
            ' 3. Create a file converter
            Dim converter As FileSvgConverter = New FileSvgConverter(settings)
            ' 4. Perform the conversion to XAML
            converter.Convert(svgTestFile)
        End Sub
    
    End Module
  5. 编译并运行程序。工作目录中将生成一个 XAML 文件 Test.xaml。查看时输出将如下所示(这是 FileSvgReader 的示例)

    SvgReader.png

标记扩展:概述

这些是用于在 WPF 应用程序中处理 SVG 文件的 WPF 标记扩展或类型转换器。

目前,SVG# Reloaded 提供了一个标记扩展 SvgImageExtension,它将 SVG 源文件转换为 DrawingImage

SvgImageExtension.png
  • 如上图所示,所有渲染设置都作为属性在此标记扩展上可用。
  • 这里的主要属性是 SvgImageExtension.Source,它是 SVG 文件的路径,文件本身可以位于以下位置
    • Web/互联网:在这种情况下,路径是文件的 HTTP、FTP 等方案 URI。
    • 本地计算机磁盘:路径是 SVG 文件的绝对或相对 URI。
    • 资源:路径是 SVG 资源文件的 Microsoft Pack URI。

标记扩展:示例

为了说明,我们将创建一个如下所示的简单 WPF 应用程序,显示的每个图像都是 WPF Image 控件中的 SVG 文件

SvgImageSample.png
  1. 在 C# 或 VB.NET 中创建一个 .NET 3.5 WPF 应用程序,我们将其命名为 SvgImageSample 并重命名主窗口 MainWindow
  2. 如上所述,添加 SVG# Reloaded 程序集的 WPF 包。
  3. 将生成的 XAML 代码修改为以下内容(C# 或 VB.NET 代码未修改)
    <Window x:Class="SvgImageSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="SvgImage Sample" Height="346" Width="409" Background="White">
        <Window.Resources>
            <ResourceDictionary> 
                <sys:String x:Key="WebFile">
                    http://upload.wikimedia.org/wikipedia/commons/c/c7/SVG.svg
                </sys:String>
            </ResourceDictionary>
        </Window.Resources>
        <DockPanel>
            <TabControl SelectedIndex="0" OverridesDefaultStyle="False">
                <TabItem>
                    <TabItem.Header>By Local File</TabItem.Header>
                    <TabItem.Content>  
                        <!-- 1. Load local SVG file, using the constructor -->
                        <Image Source="{svgc:SvgImage ../Test1.svg}"/>        
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>By Web File</TabItem.Header>
                    <TabItem.Content>    
                        <!-- 2. Load Web SVG file, using the constructor. -->
                        <Image Source="{svgc:SvgImage {StaticResource WebFile}}"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>By Local/Resource File</TabItem.Header>
                    <TabItem.Content>
                        <!-- 3. Load local, using the constructor and a property. -->
                        <Image Source="{svgc:SvgImage Test2.svg, TextAsGeometry=True}"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>By Sub-Folder File</TabItem.Header>
                    <TabItem.Content>
                        <!-- 4. Load local, using constructor - works, but not 
                         recommended syntax, simply use /SubFolder/Test3.svg  -->
                        <Image Source="{svgc:SvgImage \\SubFolder\\Test3.svg}"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>By Local/Resource File</TabItem.Header>
                    <TabItem.Content>
                        <!-- 5. Load resource, using the constructor. -->
                        <Image Source="{svgc:SvgImage /Resources/Test.svg}"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>By Properties</TabItem.Header>
                    <TabItem.Content>
                        <!-- 6. Load resource, using property. -->
                        <Image Source="{svgc:SvgImage Source=/Resources/Test.svg}"/>
                    </TabItem.Content>
                </TabItem>
            </TabControl>
        </DockPanel>
    </Window>

    注意:如上所示,本地相对路径和资源路径相似,在这种情况下,运行时会搜索本地目录,如果找不到此类文件,则假定它在资源中。

  4. 编译并运行程序。

Viewbox 控件:概述

SvgViewbox 控件是一个 WPF Viewbox 派生控件,用于在 WPF 应用程序中查看 SVG 文件,并允许您使用所有 Viewbox 装饰器属性。

SvgViewbox.png

它封装了一个绘图画布而不是图像,因此在未来的绘图画布版本中将支持交互性。

主要属性是 SvgViewbox.Source,它是一个 System.Uri,指定 SVG 文件的路径。

Viewbox 控件:示例

为了说明,我们将创建以下 WPF 示例应用程序

SvgViewboxSample.png
  1. 创建一个 WPF 应用程序项目,命名为 SvgViewboxSample,类似于前面章节的步骤。
  2. 将主窗口的 XAML 修改为以下内容
    <Window x:Class="SvgViewboxSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        Title="SvgViewbox Sample" Height="346" Width="430" Background="White">
        <DockPanel>
            <TabControl SelectedIndex="0" OverridesDefaultStyle="False">
                <TabItem>
                    <TabItem.Header>Web File</TabItem.Header>
                    <TabItem.Content>
                        <!-- 1. Load Web SVG file -->
                        <svgc:SvgViewbox Source=
                "http://croczilla.com/bits_and_pieces/svg/samples/tiger/tiger.svg"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Local File 1</TabItem.Header>
                    <TabItem.Content>
                        <!-- 2. Load local SVG file -->
                        <svgc:SvgViewbox Source="../Test1.svg"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Local File 2</TabItem.Header>
                    <TabItem.Content>
                        <!-- 3. Load local SVG file -->
                        <svgc:SvgViewbox Source="Test2.svg" TextAsGeometry="True"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Sub-Folder File</TabItem.Header>
                    <TabItem.Content>
                        <!-- 4. Load local sub-folder SVG file  -->
                        <svgc:SvgViewbox Source="\SubFolder\Test3.svg"/>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Resource File</TabItem.Header>
                    <TabItem.Content>
                        <!-- 5. Load Resource SVG file -->
                        <svgc:SvgViewbox Source="/Resources/Test.svg" 
    					Stretch="Uniform"/>
                    </TabItem.Content>
                </TabItem>
            </TabControl>
        </DockPanel>
    </Window> 
  3. 编译并运行程序。

Canvas 控件:概述

SvgCanvas 控件是一个 WPF Canvas 派生控件,用于在 WPF 应用程序中查看 SVG 文件,并允许您使用所有画布属性。

SvgCanvas.png
  • 它派生自绘图画布而不是通用画布控件,因此在未来的绘图画布版本中将支持交互性。
  • 主要属性是 SvgCanvas.Source,它是一个 System.Uri,指定 SVG 文件的路径。

Canvas 控件:示例

为了说明,我们将创建以下 WPF 示例应用程序

SvgCanvasSample.png
  1. 创建一个 WPF 应用程序项目,命名为 SvgCanvasSample,类似于上述步骤。
  2. 将主窗口的 XAML 修改为以下内容
    <Window x:Class="SvgCanvasSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        Title="SvgCanvas Sample" Height="332" Width="413" Background="White">
        <DockPanel>
            <TabControl SelectedIndex="0" OverridesDefaultStyle="False">
                <TabItem>
                    <TabItem.Header>Web File</TabItem.Header>
                    <TabItem.Content>
                        <ScrollViewer CanContentScroll="False" 
                           VerticalScrollBarVisibility="Auto" 
                           HorizontalScrollBarVisibility="Auto">                        
                            <!-- 1. Load Web SVG file -->
                            <svgc:SvgCanvas Source=
           "http://croczilla.com/bits_and_pieces/svg/samples/butterfly/butterfly.svg"/>
                        </ScrollViewer>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Local File 1</TabItem.Header>
                    <TabItem.Content>
                        <ScrollViewer CanContentScroll="False" 
                           VerticalScrollBarVisibility="Auto" 
                           HorizontalScrollBarVisibility="Auto">                        
                            <!-- 2. Load local SVG file -->
                            <svgc:SvgCanvas Source="../Test1.svg"/>
                        </ScrollViewer>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Local File 2</TabItem.Header>
                    <TabItem.Content>
                        <ScrollViewer CanContentScroll="False" 
                           VerticalScrollBarVisibility="Auto" 
                           HorizontalScrollBarVisibility="Auto">
                            <!-- 3. Load local SVG file -->
                            <svgc:SvgCanvas Source="Test2.svg"/>
                        </ScrollViewer>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Sub-Folder File</TabItem.Header>
                    <TabItem.Content>
                        <ScrollViewer CanContentScroll="False" 
                           VerticalScrollBarVisibility="Auto" 
                           HorizontalScrollBarVisibility="Auto">
                            <!-- 4. Load local sub-folder SVG file  -->
                            <svgc:SvgCanvas Source="\SubFolder\Test3.svg"/>
                        </ScrollViewer>
                    </TabItem.Content>
                </TabItem>
                <TabItem>
                    <TabItem.Header>Resource File</TabItem.Header>
                    <TabItem.Content>
                        <ScrollViewer CanContentScroll="False" 
                           VerticalScrollBarVisibility="Auto" 
                           HorizontalScrollBarVisibility="Auto">
                            <!-- 5. Load Resource SVG file -->
                            <svgc:SvgCanvas Source="/Resources/Test.svg"/>
                        </ScrollViewer>
                    </TabItem.Content>
                </TabItem>
            </TabControl>
        </DockPanel>
    </Window>  
    
  3. 编译并运行程序。

示例应用程序

SVG# Reloaded 附带了一些应用程序。以下两个可能对您感兴趣。

WpfTestSvgSample

这是一个用于浏览 SVG 文件目录(递归)的应用程序。

TestApplication.png

WpfW3CSvgTestSuite

这是一个用于查看 W3C 测试套件兼容结果的应用程序。它有两个窗格:顶部和底部。顶部窗格是生成的 WPF 输出,底部窗格是 W3C 预期的输出图像。

根据测试结果,SVG# Reloaded 是 WPF 最完整的 SVG 阅读器!

您可以从项目站点下载精简版测试套件,因为它的尺寸仍然超出了 CodeProject 文件上传限制。

TestSuiteApplication.png

关注点

WPF 的许多部分仍在开发中。例如,GDI+ 中支持良好的垂直文本(如日语)仍然缺失。以前,团队声称是由于时间不足,但 WPF 4.0 发布时仍然没有,人们无法知道他们下一个借口是什么!

致谢

SVG# Reloaded 使用了来自文章和其他开源项目的源代码,没有这些,这可能是不可能的。我们谨此感谢这些优秀文章和项目的作者。

结论

据我所知,这是用于处理 SVG 文件到 WPF 转换的最完整库。然而,SVG 本身是一个庞大而复杂的规范,尽管人们会期望最现代的框架 WPF 能够轻松处理这个已有十年历史的规范,但它却力不从心。

在此版本中,到 WPF 的转换已经足够完善,但是,控件在最终发布之前还需要一些改进。

在未来的版本发布中,我将进一步致力于支持这些规范。欢迎对此方向的任何帮助。

历史

  • 2010 年 11 月 16 日:SharpVectors 1.0 Beta 初始发布
  • 2010 年 11 月 17 日:改进了格式并添加了致谢部分
© . All rights reserved.