【问题标题】:Read in coordinates of SVG path / polygon读取 SVG 路径/多边形的坐标
【发布时间】:2020-07-13 18:34:11
【问题描述】:

我正在尝试将使用 illustrator 创建的 SVG 文件中的路径坐标导入 R。

我想我可以用grImport2 将 SVG 读入 R,理论上应该是导入 SVG 文件,但我认为它们可能只处理由 Cairo 设备生成的 SVG 文件。

假设我要导入以下 .svg 文件:

这是我加载 SVG 文件的尝试。如果我正确阅读了内容,它应该只包含 1 个(复杂的)路径。该警告与我在加载由 Adob​​e Illustrator 创建的 SVG 文件时收到的警告相同。请注意,下面的代码会卡住一段时间!

file <- "https://upload.wikimedia.org/wikipedia/commons/d/db/Brain_Drawing.svg"
download.file(file, tmp <- tempfile(fileext = ".svg"))

# Don't run the following line, it will get your R session stuck!
x <- grImport2::readPicture(tmp)
#> Warning message:
#> In checkValidSVG(doc, warn = warn) :
#>   This picture was not generated by Cairo graphics; errors may result

unlink(tmp)

我的理想输出是data.frame,其中至少包含xy(锚)点坐标,也许还有一些可以区分不同路径的元数据。我不需要内插曲线和圆弧或类似的东西。

还有其他我不知道的包可能会导入这个吗?有没有办法将 SVG 转换为我可以读入 R 的格式?

【问题讨论】:

    标签: r svg


    【解决方案1】:

    很好的问题 Teunbrand - 感谢您的发帖。这个问题似乎让grImport2 阅读非开罗的svg。所以实际上,我们只需要另一个翻译步骤:使用包rsvg 读取非开罗的svg 并用开罗写同样的东西。奇怪的是,它有一个功能可以做到这一点,称为rsvg_svg。所以我们可以在一行中将远程文件读取为Picture 对象,甚至无需创建本地 tmp 文件:

    file <- "https://upload.wikimedia.org/wikipedia/commons/d/db/Brain_Drawing.svg"
    svg  <- grImport2::readPicture(rawToChar(rsvg::rsvg_svg(file)))
    

    不幸的是,Picture 是一个深度列出的 S4 对象,它比 grob 树更难导航。我敢肯定,像您这样的人可以将其强制转换为数据框,但这不是微不足道的,我不会在这里尝试。至少组件本身看起来很容易收获:

    svg@content[[1]]@content[[1]]@d@segments[[3]]
    
    #> An object of class "PathCurveTo"
    #> Slot "x":
    #>  [1]  791.8359 789.5286 787.1382 784.6293 782.0041 779.2962 776.5600 773.8555 771.2318 
    #>   [10] 768.712 766.2875 764.8359
    #> 
    #> Slot "y":
    #>   [1] 8.191406 8.209760 8.239691 8.282891 8.340521 8.412835 8.499026 8.597442 8.706126 
    #>  [10] 8.82357  8.949580 9.031250
    

    不管怎样,有一些不错的实用功能可以让你做一些很酷的事情:

    brainGrob <- grImport2::pictureGrob(svg)
    ggplot2::ggplot() + ggplot2::geom_point(ggplot2::aes(1, 1))
    grid::grid.draw(brainGrob)
    

    我以前没有见过在网格中绘制任意 SVG,所以我很高兴找到这个,这是由您的问题提示的。再次感谢。

    【讨论】:

    • 谢谢艾伦,这太棒了!我最大的担心是我必须手动解析 XML 文件(半),但是这种方法似乎为您完成了工作,这太棒了!我不介意 S4 对象,我会想办法解决它。一旦我有一种巧妙的方法可以转换为普通的 data.frames,我就会放弃更新。
    • 伟大的@teunbrand。我正在尝试将 C++ SVG 解析器移植到 github 托管的包中,但这实际上看起来很快。在与此类似的主题上似乎有一些部分回答的 SO 问题,因此,如果您设法获得一种将 SVG 强制转换为数据帧的可靠方法,它将成为一个非常有用的 CRAN 包。
    • > 一旦我有一种巧妙的方法来转换为普通的 data.frames,我就会放弃更新。你能一次性解决这个问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 2015-01-10
    相关资源
    最近更新 更多