有没有一种方法可以批量将SVG导出为PNG?

我有这些SVG文件,想要将它们导出为PNG图像。我可以使用Inkscape导出它们,但这意味着需要打开每个文件并将其导出为PNG,这样效率不高(我有成百上千个文件)。
请问有什么方法可以实现这个需求吗?
5个回答

看起来你可以使用Inkscape的命令行功能:
`#{INKSCAPE_PATH} -z -f #{source_svg} -w #{width} -j -e #{dest_png}`

更多细节

我想你可以编写一个简单的 bash 脚本来处理所有的 SVG 文件:

#!/bin/sh

for file in *.svg
do
     /usr/bin/inkscape -z -f "${file}" -w 640 -e "${file}.png"
done

上面的示例将当前目录中的所有.svg文件转换为输出文件,并在文件名后添加.png扩展名。

我试图导出几百个SVG文件,如何设置导出值(目标)使它们保持原有的名称?因为这对少量文件来说似乎可以正常工作。 - Uri Herrera
@UriHerrera:我更新了答案。 - Sergey
所有的文件都以{file}.svg.png格式保存,而不是{file}.png格式?如何修复这个问题?另外,在原始的SVG文件中,底部右下角出现了一个小的快捷图标,但在转换为PNG格式后消失了(我正在尝试转换图标包)。 - Tosho
@Tosho 目前我使用的是Windows系统,但应该是类似这样的:http://pastebin.com/TEDfvxPC - user31389
2@Tosho 你也可以使用${file%svg}png来完成。你可以在这里阅读更多可能性。 - jja
如果其他人也通过brew安装了Inkscape,你需要使用/usr/local/bin/inkscape。我还使用"$PWD${file}"来传递绝对文件路径。 - Atav32

受之前接受的答案的启发,我想出了这个一行代码的解决方案:
对于Inkscape版本0.92.4及更早版本:
for file in *.svg; do inkscape "$file" -e "${file%svg}png"; done

这样你就不需要调用脚本了。如果你愿意的话,你可以创建一个别名来将当前目录中的所有svg文件转换为png文件。
alias svgtopng='for file in *.svg; do inkscape "$file" -e "${file%svg}png"; done'

对于Inkscape版本1.0 Beta及更高版本:

for file in *.svg; do inkscape "$file" -o "${file%svg}png"; done

这样你就不需要调用脚本了。如果你愿意的话,你可以创建一个别名来将当前目录中的所有svg文件转换为png文件。
alias svgtopng='for file in *.svg; do inkscape "$file" -o "${file%svg}png"; done'

1${file%svg}png是一个很棒的技巧!我以前从没见过这样的用法。 - Chester
1我觉得文件名中带有空格的情况下,这个方法不起作用。 - Saren Tasciyan
你可以用双引号将$file和${file%svg}png包起来。这样可以解决“文件名中带有空格时无法正常工作”的问题。 - sotirov

图形化的鹦鹉螺脚本

概述

命令行非常适合批量转换,但有时您可能不想离开图形用户界面的舒适环境。这就是为什么我编写了一个基于GUI的Nautilus脚本,用于批量将SVG文件转换为PNG图像。其他支持自定义操作(例如Thunar)的文件管理器也应该被支持。

屏幕截图

enter image description here

脚本

#!/bin/bash

# NAME:         SVG2PNG
# VERSION:      0.1
# AUTHOR:       (c) 2014 Glutanimate (https://github.com/Glutanimate)
#
# DESCRIPTION:  Simple application to convert SVG files to PNG files based on DPI or resolution. 
#               Designed to work as a context menu script in file managers like Nautilus and Thunar.
#
# FEATURES:     - Converts SVG image file to PNG raster of a specific DPI or width
#               - SVG preview
#               - choose between converting the full SVG page or only the cropped image
#
# DEPENDENCIES: inkscape imagemagick yad
#               YAD (1) is an advanced for of Zenity with many improvements. It's not included in the
#               official Ubuntu repos yet (2) but can be installed from a webupd8 PPA (3)
#
# LICENSE:      MIT license (http://opensource.org/licenses/MIT)
#
# NOTICE:       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
#               INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
#               PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
#               LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
#               TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
#               OR OTHER DEALINGS IN THE SOFTWARE.
#
#
# USAGE:        SVG2PNG image1.svg image2.svg [..]
#               I recommend installing this script as a context menu action for your file manager.
#               Instructions for Nautilus may be found on AskUbuntu (4).
#
# NOTES:        The script uses convert for previews because it's faster. For optimal results
#               the actual conversion is done with inkscape's command line interface.
#
# LINKS:        (1) https://code.google.com/p/yad/
#               (2) https://bugs.launchpad.net/ubuntu/+bug/796633
#               (3) https://launchpad.net/~webupd8team/+archive/y-ppa-manager
#               (4) https://askubuntu.com/questions/236414/how-can-i-install-a-nautilus-script

############## DIALOGS ###################

TITLE="SVG to PNG"
ICON="svg"

############## USGCHECKS #################

# checks if user selected an item

if [ $# -eq 0 ]
  then
      yad --title="$TITLE" \
          --image=dialog-error \
          --window-icon=dialog-error \
          --class="$WMCLASS" \
          --text="Error: no file selected" \
          --button="Ok":0
      echo "Error: no file selected"
      exit
fi

############### GLOBVAR ##################

SVGFILES="$@"
TEMPDIR=$(mktemp -d)
PREVIEWIMG="$TEMPDIR/svgpreview.png"

############### CLEANUP ##################

trap "rm -r $TEMPDIR" EXIT 

############## FUNCTIONS #################

converttosvg_dpi(){

echo "Converting based on DPI."

while [ $# -gt 0 ]; do

    echo "$# file(s) left to convert."
    SVGFILE="$1"
    FILESTEM="${SVGFILE%%.*}"
    PNGFILE="$FILESTEM".png
    inkscape "$SVGFILE" -z --export-dpi="$DPI" \
    --"$AREASETTING" --export-png="$PNGFILE"
    shift

done
echo "Done."

}

converttosvg_res(){

echo "Converting based on Width."

while [ $# -gt 0 ]; do

    echo "$# file(s) left to convert."
    SVGFILE="$1"
    FILESTEM="${SVGFILE%%.*}"
    PNGFILE="$FILESTEM".png
    inkscape "$SVGFILE" -z --export-width="$WIDTH" \
    --"$AREASETTING" --export-png="$PNGFILE"
    shift

done
echo "Done."

}

createpreview() {
convert -resize 128x "$1" "$PREVIEWIMG"
}

getsettings() {

SETTINGS=$(yad --window-icon "$ICON" --image "$PREVIEWIMG" --width 300 --height 200 --always-print-result \
--form --separator="|" --title="$TITLE" --text "Please choose the DPI or resolution to convert to." \
--field="DPI:NUM" 10[!80..600[!10]] --field="Width in px:NUM" 16[!16..4096[!16]] \
--field="Area:":CB "Drawing"\!"Page" \
--button="Convert based on DPI:2" --button="Convert based on Resolution:3" --button="gtk-cancel:1")

RET=$? # Exit code?

if [ "$RET" = 252 ] || [ "$RET" = 1 ]  # WM-Close or "Abort"
  then
      echo "Exiting..."
      exit
fi

DPI=$(printf %.0f $(cut -d "|" -f 1 <<<"$SETTINGS")) #round values
WIDTH=$(printf %.0f $(cut -d "|" -f 2 <<<"$SETTINGS"))
AREA=$(cut -d "|" -f 3 <<<"$SETTINGS")

case "$AREA" in

Drawing)
  AREASETTING="export-area-drawing"
  ;;

Page)
  AREASETTING="export-area-page"
  ;;

esac

echo "DPI set to $DPI"
echo "Width set to $WIDTH"
echo "Area set to $AREA"

}


################ MAIN ####################

createpreview "$1"
getsettings

case "$RET" in

2)
  echo 2
  converttosvg_dpi "$@"
  ;;

3)
  echo 3
  converttosvg_res "$@"
  ;;

esac

exit 0

我会尽力保持这个答案的更新,但请查看我的Github存储库以获取脚本的最新版本。

安装

适用于所有Nautilus脚本的通用安装说明可以在此处找到。以下命令应该涵盖所有必要的依赖项:

sudo add-apt-repository ppa:webupd8team/y-ppa-manager
sudo apt-get update
sudo apt-get install yad inkscape imagemagick

如需更多信息,请参阅上方的脚本头部。

使用方法

安装脚本后,您应该能够从文件管理器的上下文菜单中调用它。只需选择一个或多个SVG文件,然后点击上下文菜单中的适当条目。一个GUI对话框应该弹出,提供了几个有关转换的选项。

您可以根据DPI或宽度来转换SVG。在两种情况下,纵横比都将保持不变。在点击转换按钮之前,请确保提供所需的DPI或宽度。

您还可以选择导出完整的SVG文件或仅裁剪的绘图。如果您的SVG画布有很多空白空间,建议选择“绘图”作为导出选项。


这是一个稍微不同的替代解决方案,使用一种更易读的脚本语言 - Python。它可以批量导出所有的SVG文件。如果你正在进行Android开发,并且需要从单个SVG文件创建多个PNG文件,那么这个解决方案特别适合你。
免责声明:我编写了这个库,希望能帮到某些人。
点击这里
对于简单的使用,将库下载到一个文件夹中,将SVG文件放在同一个文件夹中,然后运行。
python exporter.py

在命令行/终端中,当您 cd 到文件夹后。如需更高级的选项,请查看 README

谢谢David,我已经编辑了我的回答以提供更多细节! - Kevin Lee

如果不是所有文件,而只有某些SVG文件需要转换为PNG,可以使用sed自动生成文件名。
inkscape --without-gui --export-width=1280 --export-png=`echo $1 |sed -e 's/svg$/png/'` $1