使用 Aspose.SVG Builder API 进行高级 SVG 创建和修改 – C#

使用 Aspose.SVG 的 Builder API 进行高效的 SVG 管理

探索Aspose.SVG Builder API专为简化 C# 中 SVG 元素的创建和更新而设计。

本文深入研究了 Aspose.SVG 的 Builder API 中使用的 Fluent Builder 模式和mixins,展示了其在 SVG 操作方面的效率。您将了解 SVGElementBuilder 类、其专用构建器以及它们如何简化 SVG 编程。

SVG Builder背后的基本原理

在 Web 和图形开发领域,管理可扩展矢量图形 (SVG) 可能是一项复杂的任务,需要在精度和效率之间取得平衡。 Aspose.SVG Builder API的开发就是为了解决这一挑战,为开发人员提供了一个强大的工具,用于以简化的方式创建和更新 SVG 元素。

SVG 构建器的开发受到以下几个关键因素的推动:

为了实现这些目标,Aspose.SVG SVG Builder API采用了 Fluent Builder 模式,这是一种完全满足 SVG 操作的简单性、清晰度和多功能性需求的设计方法。

Aspose.SVG 中的元素生成器:简化 SVG 创建和修改

在Aspose.SVG Builder API中,所有元素构建器(例如SVGSVGElementBuilderSVGGElementBuilder等)都继承自核心SVGElementBuilder类。这种继承结构简化了创建和修改 SVG 元素的过程,确保了不同类型元素之间的一致性和效率。

创建新元素

元素构建器提供Build(Document document)方法,允许创建新的 SVG 元素并将其添加到 SVG 文档中。

示例:创建新的 SVG 元素:

 1using (var document = new SVGDocument())
 2{
 3    // Create a new <g> (group) element using SVGGElementBuilder
 4    var gElement = new SVGGElementBuilder()
 5        // Additional element configurations
 6        // ...
 7        .Build(document);
 8    // Append the newly created <g> element to the root <svg> element
 9    document.RootElement.AppendChild(gElement);
10}

在此示例中,SVGGElementBuilder用于创建新组<g>元素。 Build() 方法生成该元素,然后将其附加到根 <svg> 元素。

修改现有元素

元素构建器还提供Build(T element)方法来更新现有 SVG 元素,允许修改其属性或样式。

示例:SVG 元素的更新:

 1using (var document = new SVGDocument())
 2{
 3    // Assume an existing SVG element is part of the document
 4    var existingSvgElement = document.FirstChild as SVGSVGElement;
 5
 6    // Update the existing SVG element using SVGSVGElementBuilder
 7    new SVGSVGElementBuilder()
 8        // Additional element configurations
 9        // ...
10        // The existingSvgElement is now updated with new configurations
11        .Build(existingSvgElement);
12}

在此示例中,SVGSVGElementBuilder用于更新现有的 SVG 元素。 Build()方法将新配置应用于提供的元素,并在 SVG 文档中更新它。

了解 Fluent Builder

在Aspose.SVG SVG Builder API 中,采用Fluent Builder模式来简化SVG元素的构建和更新,使过程直观且不易出错。

Aspose.SVG API 中这种模式的本质是配置 SVG 元素然后返回构建器对象的方法。这种设计能够以连贯、线性的方式链接方法,这对于降低与创建和操作 SVG 元素相关的复杂性特别有效。 在此上下文中,lambda 表达式用于增强构建器配置方法的清晰度和简洁性。 Lambda 表达式允许以详细而紧凑的方式定义 SVG 元素的属性和样式。例如,当添加圆形元素时,lambda 表达式提供内联、可读的配置:

1var svgElement = new SVGSVGElementBuilder()
2    .AddCircle(circle => circle
3        .Cx(50).Cy(50).R(20)
4        .Fill(Color.Blue).Stroke(Paint.None)
5        .StrokeWidth(2))
6    .Build();

这里,circle => Circle.Cx(50).Cy(50).R(20).Fill(Color.Blue).Stroke(Paint.None).StrokeWidth(2)是配置圆的简洁方法属性,例如中心、半径、填充和描边。这种方式不仅简化了元素配置,还增强了代码的可读性和可维护性。

使用mixins实现 Fluent Builder 模式

在 SVG Builder API中,Fluent Builder 模式通过使用mixins进一步增强。

理解mixins

面向对象编程中的mixin是一种将附加属性或方法包含到类中的方法。它们允许组合和重用多个行为或属性,而无需诉诸传统的类层次结构。这在多个对象共享公共功能但不一定属于同一类层次结构的情况下特别有用。

Aspose.SVG Builder 中的mixins

Aspose.SVG Builder采用mixins来创建灵活的模块化方法来构建 SVG 元素。通过使用接口作为mixins,API 允许根据需要组合和定制 SVG 元素的不同方面。

mixin实现示例:

考虑来自 Aspose.SVG SVG Builder API 的以下代码片段:

 1public static partial class SVGBuilderExtensions
 2{
 3    public static TBuilder Id<TBuilder>(this TBuilder builder, string value)
 4        where TBuilder : ISVGElementBuilder, ICoreAttributeSetter
 5    {
 6        return builder.SetAttribute("id", value);
 7    }
 8}
 9
10public interface ICompositeAttributeSetter :
11    IConditionalProcessingAttributeSetter,
12    ICoreAttributeSetter,
13    IGlobalEventAttributeSetter,
14    IDocumentElementEventAttributeSetter,
15    IGraphicalEventAttributeSetter,
16    IPresentationAttributeSetter { }
17
18public class SVGAElementBuilder : SVGElementBuilder<SVGAElement>,
19    ICompositeElementBuilder,
20    ICompositeAttributeSetter
21{
22    // Example usage
23    .AddA(a => a.Id("one"))
24}

在此示例中,SVGBuilderExtensions定义了一个扩展方法Id,用于设置 SVG 元素的id属性。 TBuilder类型参数仅限于同时实现ISVGElementBuilderICompositeAttributeSetter的类型。这种方法允许高度定制和灵活性,因为ICompositeAttributeSetter本身是由各种属性设置接口组成的mixins。

Aspose.SVG Builder API 中的Syntax Sugar:增强优雅性和效率

Aspose.SVG SVG Builder API引入了Syntax Sugar来进一步细化 SVG 创建和操作的过程。这包括各种 SVG 元素的嵌套构建器,提供更直观、更有效的方式来定义复杂的 SVG 结构。

建设者中的建设者


路径生成器(PathBuilder类)

PathBuilder 类提供了一种创建路径元素的微妙方法。它允许使用流畅的语法定义复杂的路径:

 1.AddPath(p => p
 2    // 'D' method defines the 'd' attribute, which contains the path data.
 3    .D(d => d
 4        // 'M' sets the starting point of the path (Move to x=5, y=0).
 5        .M(5, 0)
 6        // 'L' draws a line from the current point to the new point (Line to x=10, y=10).
 7        .L(10, 10)
 8        // Another 'L' to draw a line to a new point (Line to x=0, y=10).
 9        .L(0, 10)
10        // 'Z' closes the path by drawing a line to the starting point.
11        .Z())
12    // Sets the fill color of the path to blue and removes the stroke (border).
13    .Fill(Color.Blue).Stroke(pt => pt.None()))

在此示例中,SVG 构建器的AddPath方法用于定义路径元素。传递给 PathBuilder 类的 D 方法的 lambda 表达式使用 SVG 路径命令指定路径的形状,例如M(move to)、L(line to)和Z(close path)。

此外,路径可以定义为字符串,允许直接集成 SVG 路径数据:

1.D(d => d.AddPathSegment("M199 89.3 C206.6 66.6 235.8 13.2 270 30.3 286.6 38.6 298.9 59.4 310 73.3 ..."))

转换生成器(TransformBuilder 类)

TransformBuilder 类有助于对 SVG 元素进行转换:

 1.AddG(g => g
 2    // 'Transform' method applies transformations to the group element.
 3    .Transform(t => t
 4        // 'Translate' moves the element by x=130 and y=40 units.
 5        .Translate(130, 40)
 6        // 'Scale' uniformly scales the element by a factor of 8.
 7        .Scale(8)
 8        // Another 'Scale' to adjust the scaling differently in x and y directions.
 9        .Scale(.2, .2)
10        // Final 'Translate' to move the element by x=-5 and y=-5 units.
11        .Translate(-5, -5)))

在这里,诸如平移和缩放之类的多个转换被链接在一起以操作组元素<g>

规则生成器(RuleBuilder 类)

RuleBuilder 类有助于在 SVG 中定义样式:

1.AddStyle(st => st
2    .Type("text/css")
3    .AddRule("@font-face", r => r
4        .Opacity(.5)
5        .FontFamily("FreeSansWoff")
6        .Attribute("src", "url(woffs/FreeSans.woff) format(\"woff\")")
7    )
8)

此示例演示如何在 SVG 中添加 @font-face 的 CSS 规则。

Paint Builder(PaintBuilder 类)

PaintBuilder 用于指定 linesfill 属性:

1.AddPattern(p => p.Id("Pat3a")
2    .Rect(0, 0, 20, 20)
3    .PatternUnits(CoordinateUnits.UserSpaceOnUse)
4    .AddRect(r => r.Rect(0, 0, 10, 10).Fill(Color.FromArgb(0x99, 0x33, 0xdd)))
5    .AddRect(r => r.Rect(10, 0, 10, 10).Fill(Color.Green))
6    .AddRect(r => r.Rect(0, 10, 10, 10).Fill(Color.Blue))
7    .AddRect(r => r.Rect(10, 10, 10, 10).Fill(Color.Yellow))
8)
9.AddRect(r => r.Rect(20, 20, 440, 80).Fill(f => f.PaintServerId("Pat3a")))

在此示例中,首先使用AddPattern定义图案,其中组合各种彩色矩形以创建复杂的填充图案。该模式被赋予标识符"Pat3a"。随后,使用Fill方法和PaintServerId("Pat3a")引用先前定义的模式,将此模式应用于矩形元素。

使用枚举作为预定义的属性值

枚举在Aspose.SVG Builder API中发挥着重要作用。它们为某些属性提供预定义值,从而降低由于拼写错误而出现错误的风险,并提供方便的有效选项列表。 例如:

 1[PublicAPI(TargetProduct.SVG)]
 2public enum CoordinateUnits
 3{
 4    [Description("userSpaceOnUse")]
 5    UserSpaceOnUse,
 6
 7    [Description("objectBoundingBox")]
 8    ObjectBoundingBox,
 9}
10
11// Using the enum in a builder
12.AddClipPath(cp => cp.Id("one")
13    .ClipPathUnits(CoordinateUnits.ObjectBoundingBox))

这里,CooperativeUnits枚举为clipPathUnits属性提供特定值,确保输入正确且标准化。

更好地理解使用 SVG 构建器的附加示例

为了进一步说明Aspose.SVG Builder API的功能和多功能性,让我们深入研究一些实际示例,这些示例展示了创建和操作 SVG 元素的高级功能和技术。

创建过滤器

以下是使用Aspose.SVG Builder API创建复杂过滤器的示例:

 1using (var document = new SVGDocument())
 2{
 3    var svg = new SVGSVGElementBuilder()
 4        .WithXlink()
 5        .Width(200).Height(200)
 6        .AddDefs(d => d
 7            // Defining a filter with the ID 'spotlight'
 8            .AddFilter(f => f.Id("spotlight")
 9                // Adding an feImage, a filter primitive used for image processing
10                .AddFeImage(i => i
11                    .ColorInterpolationFilters(ColorInterpolation.SRGB)
12                    .Href("normal.png") // Source of the image
13                    .Result("img")) // Resultant image after applying filter
14                // Adding an feFlood, used to fill the filter subregion with a single color
15                .AddFeFlood(fl => fl
16                    .ColorInterpolationFilters(ColorInterpolation.SRGB)
17                    .Result("floodFill") // Resultant graphic of the flood fill
18                    .X(0).Y(0).Width(100, LengthType.Percentage).Height(100, LengthType.Percentage)
19                    .FloodColor(Color.FromArgb(0, 210, 2)).FloodOpacity(1))
20                // Adding an feBlend to blend the two previous results
21                .AddFeBlend(bl => bl
22                    .In("img").In2("floodFill") // Inputs to be blended
23                    .Mode(BlendMode.Color))) // Blend mode
24        // Applying the filter to a rectangle
25        .AddRect(r => r
26            .Rect(0, 0, 100, 100)
27            .Filter(fl => fl.FilterId("spotlight"))) // Reference to the defined filter
28        .Build(document.FirstChild as SVGSVGElement);
29}

在此代码片段中,我们定义了一个滤镜聚光灯,其中包括图像、洪水填充和混合效果。然后将该过滤器应用于矩形元素。

创建剪切和蒙版

通过创建剪切路径和蒙版,您可以控制 SVG 元素某些部分的可见性。具体方法如下:

 1using (var document = new SVGDocument())
 2{
 3    var svg = new SVGSVGElementBuilder()
 4        .Width(100, LengthType.Percentage).Height(100, LengthType.Percentage)
 5        .ViewBox(0, 0, 480, 360)
 6        .WithXlink()
 7        // ... additional setup ...
 8        .AddDefs(df => df
 9            // Defining a clipPath with ID 'one'
10            .AddClipPath(cp => cp.Id("one")
11                .ClipPathUnits(CoordinateUnits.ObjectBoundingBox)
12                // Adding circles to define the clipping area
13                .AddCircle(c => c.Cx(.3).Cy(.5).R(.2).Fill(p => p.None()).StrokeWidth(.15).Stroke(Color.Red))
14                .AddCircle(c => c.Cx(.7).Cy(.5).R(.2).Fill(p => p.None()).StrokeWidth(.15).Stroke(p => p.None())))
15            // Applying the clipPath to a rectangle
16            .AddRect(r => r.Rect(150, 0, 200, 200).Fill(Color.DarkBlue).ClipPath(p => p.ClipSourceId("one")))
17        )
18        .AddDefs(df => df
19            // Defining a mask with ID 'two'
20            .AddMask(m => m.Id("two")
21                .MaskUnits(CoordinateUnits.ObjectBoundingBox)
22                .MaskContentUnits(CoordinateUnits.ObjectBoundingBox)
23                .ColorInterpolation(ColorInterpolation.LinearRGB)
24                // Adding circles to define the mask area
25                .AddCircle(c => c.Cx(.3).Cy(.5).R(.2).Fill(Color.Blue).StrokeWidth(.15).Stroke(Color.Red))
26                .AddCircle(c => c.Cx(.7).Cy(.5).R(.2).Fill(Color.Blue).StrokeWidth(.15).Stroke(p => p.None())))
27            // Applying the mask to a rectangle
28            .AddRect(r => r.Rect(150, 150, 200, 200).Fill(Color.DarkBlue).Mask(p => p.MaskSourceId("two")))
29        )
30        .Build(document.FirstChild as SVGSVGElement);
31}

在此示例中,创建了两个 SVG 元素:一个带有剪切路径,另一个带有遮罩。剪切路径和蒙版都是使用圆圈定义的,这决定了它们所应用的矩形的可见区域。

创建 SVG 元素的替代简化方法

Aspose.SVG Builder API还包括一种用于创建和添加 SVG 元素的替代简化方法,通过默认参数提供效率和易用性。

简化的SVG Builder API示例:

 1// Initialize a new SVG document
 2using (var document = new SVGDocument())
 3{
 4    // Start building the main SVG element using the simplified approach
 5    var svg = new SVGSVGElementBuilder()
 6        // Adding a group element with default fill and stroke properties
 7        .AddG(g => g.FontSize(20)
 8            .AddText("<rect>", y: 30)
 9            .AddText("<circle>", y: 70)
10            .AddText("<ellipse>", y: 110)
11            .AddText("<line>", y: 150)
12            )
13        // Adding a group element with four base SVG shapes
14        .AddG(gg => gg.Fill(Color.Green)
15            .AddRect(r => r.X(105).Y(5).Width(30).Height(30))
16            .AddCircle(c => c.Cx(120).Cy(65).R(17))
17            .AddEllipse(e => e.Cx(120).Cy(105).Rx(25).Ry(13))
18            .AddLine(l => l.X1(100).X2(150).Y1(145).Y2(145).Stroke(Color.Green))
19            )
20        // Build and append the SVG element to the document
21        .Build(document.FirstChild as SVGSVGElement);
22    document.Save("example.svg");
23}

在此示例中,SVG Builder API用于使用更直接、更高效的方法构建全面的 SVG 结构。对大小、颜色和位置等常见属性使用默认参数可以快速开发标准 SVG 元素,同时仍然提供根据需要进行自定义的选项。

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.