我想使用R读取SVG文件,根据数据值更改SVG文件,然后将SVG导出为光栅图像,如png。
通过一些研究,我已经确定SVGMapping包会让我在那里使用,但是这个包已经从CRAN存储库中删除了,因此我对将它用于我可能依赖的任何东西都很谨慎。
因为SVG是XML,我的计划是使用XML包来改变我的SVG文件的属性。然后我想使用shell函数调用inkscape将SVG转换为PNG。
我在浏览XML结构时遇到了问题。正如您在下面的SVG中看到的,我创建了三个不同颜色的矩形。我想用R来改变颜色。
我可以在SVG中阅读并使用以下内容导航到属性:
doc <- xmlTreeParse("c:\\Temp\\drawing.svg", getDTD = F)
doc$children$svg$children$g$children[1]$rect$attributes
然后我可以使用以下方式提取所有样式信息:
doc$children$svg$children$g$children[1]$rect$attributes["style"]
但是,结果只是一个包含填充,描边,不透明等值的字符串。
"fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
有没有办法选择一个样式属性,比如填充,所以我可以添加一个新的颜色代码?
我猜我最终可能会使用基于正则表达式的东西,但我想要问一下是否有另一种方法(即更简单!)来浏览样式属性。
SVG文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="New document 1">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.53183594"
inkscape:cx="375"
inkscape:cy="520"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="739"
inkscape:window-height="558"
inkscape:window-x="175"
inkscape:window-y="175"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect2985"
width="180.50679"
height="165.46455"
x="30.084465"
y="225.03938"
rx="0"
ry="0" />
<rect
style="fill:#00ff00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect2985-1"
width="180.50679"
height="165.46455"
x="312.12634"
y="230.68022"
rx="0"
ry="0" />
<rect
style="fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect2985-7"
width="180.50679"
height="165.46455"
x="118.45758"
y="456.31369"
rx="0"
ry="0" />
</g>
</svg>
答案 0 :(得分:0)
目前,您需要处理XML包外部的style
。在这种情况下,您可以拆分
";"
和":"
xData <- xmlParse("c:\\Temp\\drawing.svg")
out <- lapply(xData["//svg:rect"], xmlGetAttr, name = "style")
out <- sapply(out, strsplit, ";")
out <- lapply(out, strsplit, ":")
out <- lapply(out, function(x){
sapply(x, function(y){`names<-`(y[2], y[1])})
}
)
out <- `names<-`(do.call(rbind.data.frame, out), names(out[[1]]))
out$fill <- "#000000"
out <- apply(out, 1, function(x) paste(names(out), x, sep = ':'))
out <- apply(out, 2, function(x) paste(x, collapse = ";"))
# remove old styles
lapply(xData["//svg:rect"], removeAttributes, .attrs = 'style')
# add new styles
mapply(addAttributes, node = xData["//svg:rect"], style = out)
> xData["//svg:rect"]
[[1]]
<rect id="rect2985" width="180.50679" height="165.46455" x="30.084465" y="225.03938" rx="0" ry="0" style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
[[2]]
<rect id="rect2985-1" width="180.50679" height="165.46455" x="312.12634" y="230.68022" rx="0" ry="0" style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
[[3]]
<rect id="rect2985-7" width="180.50679" height="165.46455" x="118.45758" y="456.31369" rx="0" ry="0" style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
attr(,"class")
[1] "XMLNodeSet"