c# - 如何以编程方式展平 SVG 文件中的变换?

标签 c# svg

我需要编写一些 C# 代码,以编程方式展平任何 SVG 文件的转换。

此选项在 Affinity Designer(~40 美元/Mac)或 Inkscape(FOSS)等 SVG 编辑器中可用:

Affinity Designer SVG Export Option for Flatten Transforms

但是您如何以编程方式执行此操作?偶不错SVG c# libraries不提供执行此操作的方法。

SO 上有很多关于此的讨论(即 herehereherehere)。在这些建议中,建议使用一些工具,但没有人提供执行此操作的代码(除了一些对我无用的 javascript 片段,因为它使用浏览器 API 来获取转换后的坐标)。

我需要在 C# 代码中执行此操作,因为要操作 svg 元素,我需要这些元素独立于父变换,包括椭圆弧、渐变、文本和 tspan 元素。

编辑澄清: 我不一定需要转换元素。我只需要让变换矩阵只出现在最深的子节点中,这样我就不需要再考虑父节点了。为此,我需要将所有父矩阵连接到一个矩阵中,并将其作为单个变换属性分配给 svg 元素。例如,我不一定需要转换路径或弧线、将椭圆转换为路径或重新采样位图。我只需要能够为每个元素计算一个矩阵变换,它自己的,作为变换属性分配给它,而不是每次都必须考虑所有父组变换。

最佳答案

这是对我的问题的初步回答。但是它在某些元素上仍然存在问题(具有 clip-path、mask 或 filter 属性的元素,或者使用 urls 或 defs 的元素,在展平后似乎坐标断开)。感谢任何进一步的帮助和改进。

public void FlattenNodeRecursive(XElement item) {

            var children_elements = item.Elements();

            if ( IsSVGElem(item, "g") &&
                HasAttr(item,"transform") &&
                !item.IsEmpty &&
                item.Elements().Any((XElement inner) => { return IsSVGElem(inner, "path") || IsSVGElem(inner, "text") || IsSVGElem(inner, "g"); }) &&
                item.Elements().Any((XElement inner) => { return !IsSVGElem(inner, "tspan"); })
               ) {

                XAttribute parent_attribute = item.Attribute("transform");

                foreach (var inner in children_elements) {
                    if (HasAttr(inner, "transform")) {
                            inner.Attribute("transform").SetValue(ConcatenateTransforms((parent_attribute.Value.Trim() + " " + inner.Attribute("transform").Value.Trim())).Trim());
                        } else {
                            XAttribute attribute = new XAttribute("transform", parent_attribute.Value.Trim());
                            inner.Add(attribute);
                        }
                    }

                parent_attribute.Remove();

            }

            foreach(XElement xelem in children_elements){
                if(xelem.Elements() != null) {
                    FlattenNodeRecursive(xelem);
                }

            }
        }

注意:我没有发布 HasAttr 方法或 ConcatenateTransforms 方法的源代码,因为它们非常简单,但如果有人需要,我会发布它们。

关于c# - 如何以编程方式展平 SVG 文件中的变换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40704562/

相关文章:

android - ShapeShifter 旋转使用坐标 0, 0, 而不是中心

javascript - 在 selenium 中选择 SVG 标签内的 g

c# - 预期异常时应用 Arrange-Act-Assert 模式的最佳方法

c# - 不同类别对属性(property)的不同访问

c# - 如何布置我的集成测试

c# - 从网站运行 .exe

javascript - 带有数据更新的 Angular 应用程序中的 Chrome 中的 SVG 闪烁

c# - 解析 LSM6DSL 原始值

ios - Ionic SVG 图像在 iOS 上运行缓慢

javascript - Firefox 中 d3 svg 选择的 "offsetParent"属性的类型错误