如何将大型SVG文件转换为平铺PNG?

时间:2021-11-19 09:00:56

I have a large SVG file (approx. 60 MB, 10000x10000 pixels but with the potential to get much larger), and I'm wanting to create, say, many tiled 256x256 PNG images from it (in that example there would be 1600 images; round(10000/256)^2).

我有一个大的SVG文件(大约60 MB,10000x10000像素但有可能变大),我想要创建许多平铺的256x256 PNG图像(在这个例子中会有1600个图像) ;圆形(10000/256)^ 2)。

Does anyone have any idea of how to do this on a web server (running PHP amongst other things)? I thought about rsvg, but it doesn't seem to have any functionality to modify the bounding box (and I'd rather avoid doing it manually for each section). ImageMagick might be able to do it, but I've not been having much luck with getting it to work. Using rsvg to create a large PNG and then using a tool dedicated to tiling very large images might work, but I've not had any luck finding such a thing! Speed isn't really an issue, although it is desirable, so if the worst comes to the worst, I might look into modifying the SVG's bounding box per section. I could see the generation taking forever, though!

有没有人知道如何在Web服务器上执行此操作(在其他方面运行PHP)?我想到了rsvg,但它似乎没有任何功能来修改边界框(我宁愿避免为每个部分手动操作)。 ImageMagick也许能够做到这一点,但我没有太多运气让它运转起来。使用rsvg创建一个大的PNG,然后使用专用于拼贴非常大的图像的工具可能会有效,但我没有运气找到这样的东西!速度并不是真正的问题,虽然它是可取的,所以如果最坏的情况发生,我可能会考虑修改每个部分的SVG边界框。不过,我可以看到这一代人永远在走!

Anyone know of any methods to do this?

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

Edit 2016-03-02:

I recently came back to needing an answer for this question again, and Inkscape appears to be the only tool which can render SVGs for a given area at given sizes (svgexport almost meets these requirements, but it doesn't let you change the aspect ratio).

我最近再次回到需要这个问题的答案,并且Inkscape似乎是唯一能够以给定大小为给定区域渲染SVG的工具(svgexport几乎满足这些要求,但它不允许你改变宽高比)。

My aim was to tile an SVG into 256x256 tiles, and I've now successfully made a script which can tile an arbitrarily large SVG by doing repeated renderings in inkscape of about 16,000 x 16,000 and tiling the resulting images. I've successfully rendered SVGs where the dimensions are over 500,000 x 500,000 pixels—no problems with memory usage (it just takes a long time!)

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

5 个解决方案

#1


9  

inkscape has a command line mode to export pngs, taking an optional argument to choose which area to export

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

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

#2


1  

I'd look at Apache Batik. In particular, their SVG Rasterizer looks like just what you need.

我会看看Apache Batik。特别是,他们的SVG Rasterizer看起来就像你需要的那样。

I've never used it for giant SVG files, though, so I don't know if it's optimized for that case or not.

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

#3


0  

Check out this question i posted earlier and got working.

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

If the image is only 10000x10000 the script i have in the question works best.

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

If however you want to use much bigger images check out the script in my anser.

但是,如果你想使用更大的图像,请查看我的anser中的脚本。

ImageMagick crop huge image

ImageMagick裁剪巨大的图像

#4


0  

PanoJS seems to do what you're asking about. You need to convert the SVG to a large PNG first though (e.g. using inkscape on the command line), and then use PanoJS's tilemaker to make the tiles. It is a very memory intensive beast, but if you can get it to run successfully, you can then use the PanoJS Javascript code to point to your webserver. XKCD used it for a large image describing money.

PanoJS似乎做了你要问的事情。您需要首先将SVG转换为大型PNG(例如,在命令行上使用inkscape),然后使用PanoJS的tilemaker来制作切片。它是一个非常内存密集的野兽,但如果你能让它成功运行,你可以使用PanoJS Javascript代码指向你的web服务器。 XKCD用它来描述金钱的大图像。

#5


0  

You might want to edit the source properties of your SVG (a copy), to render certain areas only. Use the "width" and "height" properties to match your desired tile size (256) and the "viewBox" to the desired tile area (for example 'viewBox="512 256 768 512"' for the 3rd tile in the second row). You could do something like this in a loop:

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

$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);

I don't know how this behaves on very large files though.

我不知道这对非常大的文件有何影响。

#1


9  

inkscape has a command line mode to export pngs, taking an optional argument to choose which area to export

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

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

#2


1  

I'd look at Apache Batik. In particular, their SVG Rasterizer looks like just what you need.

我会看看Apache Batik。特别是,他们的SVG Rasterizer看起来就像你需要的那样。

I've never used it for giant SVG files, though, so I don't know if it's optimized for that case or not.

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

#3


0  

Check out this question i posted earlier and got working.

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

If the image is only 10000x10000 the script i have in the question works best.

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

If however you want to use much bigger images check out the script in my anser.

但是,如果你想使用更大的图像,请查看我的anser中的脚本。

ImageMagick crop huge image

ImageMagick裁剪巨大的图像

#4


0  

PanoJS seems to do what you're asking about. You need to convert the SVG to a large PNG first though (e.g. using inkscape on the command line), and then use PanoJS's tilemaker to make the tiles. It is a very memory intensive beast, but if you can get it to run successfully, you can then use the PanoJS Javascript code to point to your webserver. XKCD used it for a large image describing money.

PanoJS似乎做了你要问的事情。您需要首先将SVG转换为大型PNG(例如,在命令行上使用inkscape),然后使用PanoJS的tilemaker来制作切片。它是一个非常内存密集的野兽,但如果你能让它成功运行,你可以使用PanoJS Javascript代码指向你的web服务器。 XKCD用它来描述金钱的大图像。

#5


0  

You might want to edit the source properties of your SVG (a copy), to render certain areas only. Use the "width" and "height" properties to match your desired tile size (256) and the "viewBox" to the desired tile area (for example 'viewBox="512 256 768 512"' for the 3rd tile in the second row). You could do something like this in a loop:

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

$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);

I don't know how this behaves on very large files though.

我不知道这对非常大的文件有何影响。