【问题标题】:How to convert large SVG file to tiled PNGs?如何将大型 SVG 文件转换为平铺的 PNG?
【发布时间】:2016-03-02 21:19:35
【问题描述】:

我有一个大的 SVG 文件(大约 60 MB,10000x10000 像素,但有可能变得更大),我想从中创建许多平铺的 256x256 PNG 图像(在该示例中为 1600 张图片;round(10000/256)^2)。

有没有人知道如何在 Web 服务器上执行此操作(运行 PHP 等)?我考虑过 rsvg,但它似乎没有任何修改边界框的功能(我宁愿避免为每个部分手动进行)。 ImageMagick 可能能够做到,但我一直没有让它工作的运气。使用 rsvg 创建一个大的 PNG,然后使用专门用于平铺非常大的图像的工具可能会起作用,但我没有找到这样的东西!速度并不是真正的问题,尽管它是可取的,所以如果最坏的情况出现在最坏的情况下,我可能会考虑修改每个部分的 SVG 边界框。不过,我可以看到这一代人永远消失了!

有人知道有什么方法可以做到这一点吗?

编辑 2016-03-02:

我最近再次回到需要这个问题的答案,Inkscape 似乎是唯一可以在给定大小的给定区域渲染 SVG 的工具(svgexport 几乎满足这些要求,但它不会让你改变纵横比)。

我的目标是将 SVG 平铺成 256x256 的平铺,现在我已经成功地制作了一个脚本,该脚本可以通过在 inkscape 中重复渲染大约 16,000 x 16,000 并平铺生成的图像来平铺任意大的 SVG。我已经成功渲染了尺寸超过 500,000 x 500,000 像素的 SVG——内存使用没有问题(只是需要很长时间!)

【问题讨论】:

  • 你试过 rsvg-convert,然后呢? ubuntuforums.org/showthread.php?t=820965
  • 是的;它似乎可以创建一个大的渲染,但后来我遇到了拆分它的问题。如果我错了,请纠正我,但它似乎没有任何用于平铺或指定区域的内置功能(所有运算符似乎主要用于指定比例)。
  • ImageMagick 绝对可以做到(不过先转换成巨型 png 可能更容易)

标签: php linux svg imagemagick rsvg


【解决方案1】:

inkscape 有一个命令行模式来导出 png,带一个可选参数来选择要导出的区域

inkscape vector.svg --export-png=raster.png --export-area=0:0:100:100

【讨论】:

    【解决方案2】:

    我会看看Apache Batik。特别是,他们的SVG Rasterizer 看起来正是您所需要的。

    不过,我从未将它用于大型 SVG 文件,所以我不知道它是否针对这种情况进行了优化。

    【讨论】:

    • 感谢您的建议,但我得到一个无用的“加载文档失败”。使用时!我会调查一下,但很遗憾,它似乎内存不足。
    • 这是给我最好结果的那一个
    • 当我尝试使用 Batik 从一个特别大的 SVG 生成 PNG 时,Java 核心转储。 SVG 的尺寸为 -w 6188 -h 136441。
    【解决方案3】:

    查看我之前发布的这个问题并开始工作。

    如果图像只有 10000x10000,我在问题中的脚本效果最好。

    如果您想使用更大的图像,请查看我的分析器中的脚本。

    ImageMagick crop huge image

    【讨论】:

      【解决方案4】:

      PanoJS 似乎可以满足您的要求。不过,您需要先将 SVG 转换为大的 PNG(例如,在命令行上使用 inkscape),然后使用 PanoJS 的 tilemaker 制作瓷砖。这是一个非常占用内存的野兽,但如果你能让它成功运行,你就可以使用 PanoJS Javascript 代码指向你的网络服务器。 XKCD 将其用于large image describing money

      【讨论】:

        【解决方案5】:

        您可能想要编辑 SVG(副本)的源属性,以仅渲染某些区域。使用“width”和“height”属性来匹配您想要的图块大小(256)和“viewBox”到所需的图块区域(例如“viewBox=”512 256 768 512”)用于第二行中的第 3 个图块)。 你可以在一个循环中做这样的事情:

        $sed = "sed 's/width=\"10000\"/width=\"256\"' ".$sourcefile;
        $sed .= " | sed 's/height=\"10000\"/height=\"256\"'";
        $sed .= " | sed 's/viewBox=\"0 0 10000 10000\"/viewBox=\"0 0 256 256\"'";
        exec($sed." > ".$tmpfile);
        exec('rsvg '.$tmpfile.' > '.$tilefile);
        

        我不知道这在非常大的文件上的表现如何。

        【讨论】:

          猜你喜欢
          • 2011-11-18
          • 2015-01-31
          • 2011-08-31
          • 2011-12-31
          • 2020-06-22
          • 2018-09-07
          • 1970-01-01
          • 1970-01-01
          • 2012-03-28
          相关资源
          最近更新 更多