Enable/disable 层通过命令行

Enable/disable layers via command line

我有一个脚本(如下),可以将 svg 文件导出为各种大小的 png 文件。这行得通,但我需要更多。我需要能够在导出前启用和禁用图层。 因此,例如,在 #Android 行之后,我需要 启用图层 android 并禁用图层 ios

我该怎么做?

set -x

# Windows
INKSCAPE="/C/Program Files/Inkscape/inkscape.exe"
OPTS=--export-background-opacity=0

# Note that directories must already exist before exporting to them

SVG=My_Icon.svg
DEST=generated_icons

# Android
"$INKSCAPE" -w36 $OPTS --export-png=$DEST/android/ic_launcher-ldpi.png $SVG
"$INKSCAPE" -w48 $OPTS --export-png=$DEST/android/ic_launcher-mdpi.png $SVG
"$INKSCAPE" -w72 $OPTS --export-png=$DEST/android/ic_launcher-hdpi.png $SVG
"$INKSCAPE" -w96 $OPTS --export-png=$DEST/android/ic_launcher-xhdpi.png $SVG
"$INKSCAPE" -w144 $OPTS --export-png=$DEST/android/ic_launcher-xxhdpi.png $SVG
"$INKSCAPE" -w192 $OPTS --export-png=$DEST/android/ic_launcher-xxxhdpi.png $SVG
"$INKSCAPE" -w512 $OPTS --export-png=$DEST/android/ic_launcher-web.png $SVG

# iOS
"$INKSCAPE" -w57 $OPTS --export-png=$DEST/ios/ios_icon-57.png $SVG
"$INKSCAPE" -w72 $OPTS --export-png=$DEST/ios/ios_icon-72.png $SVG
"$INKSCAPE" -w114 $OPTS --export-png=$DEST/ios/ios_icon-57-2x.png $SVG
"$INKSCAPE" -w144 $OPTS --export-png=$DEST/ios/ios_icon-72-2x.png $SVG

好吧,SVG 只是一个 XML,因此您可以设想一个工具,以您想要的方式修改 XML,将相关图层设置为 in/visible。

也就是说,可能有 更方便的选项:当通过 CLI 使用 Inkscape 进行转换时,您可以说明要导出的 XML 节点的 ID不渲染任何其他内容的标志。

来自 Inkscape 的手册页:

-i, --export-id

The area exported will be defined by the bounding box of the named object. The exported drawing will include the parts of any other objects that fall within this bounding box. The name of a given object can be found by selecting the object from within Inkscape and looking at the XML Editor. (Of course, if you do this, you may as well export using the Export Bitmap dialog.)

-j, --export-id-only

Only the specified object is exported. Must be used with the --export-id option. See above. Can be used with --export-area-canvas and --export-area-page.

为了正确参考,您可以在 Inkscape 中设置节点的 ID。

我想出了一种方法,使用 xmlstarlet 在将 InkScape SVG 传递给 InkScape 本身之前即时编辑它。

假设您有一个包含三层的 InkScape SVG,SenateBackgroundCaesarAntonius,并且您只需要组合 (SenateBackground,Caesar)(SenateBackground,Antonius) .

这是这样一个图层在 SVG 中的样子:

<g
 inkscape:label="Caesar"
 id="someID"
 inkscape:groupmode="layer"
 style="display:none"
 sodipodi:insensitive="true"
 transform="...">

作为旁注:在其他一些 SO 问题中,使用 inkscape --query-all <file> | grep "layer" 查询图层的提示已经出现,至少在我的发现中这是不可靠的,因为 inkscape 不 总是id="someID" 命名为 id="layerX"grep 查找)。对我来说,有些图层只是简单地获得了组 ID,例如 g12345.

要在元老院生成带有 Caesar 的 PNG,现在的步骤是...

  1. 阅读SVG/XML
    这可以通过 cat
  2. 来完成
  3. 通过 xmlstarlet 显示参议院背景
    在我的示例中,我处理 every 层,所以我没有任何 像 这样的限制在修改 SVG 时,记得要 show/hide 图层X/Y保存前,PNG生成脚本依赖它!.
  4. 再次通过 xmlstarlet 显示 Caesar
  5. 再次通过 xmlstarlet 管道,隐藏 Antonius
  6. 通过管道传输到 InkScape,创建 PNG
    您显然必须提供 width/height 或 DPI 不会从文件中存储的设置中获取。

命令:

cat romanSenate.svg | \
xmlstarlet edit -P -S --update "//*[@inkscape:label='SenateBackground']/@style" -v "display:inline" | \
xmlstarlet edit -P -S --update "//*[@inkscape:label='Caesar']/@style" -v "display:inline" | \
xmlstarlet edit -P -S --update "//*[@inkscape:label='Antonius']/@style" -v "display:none" | \
inkscape -z -e romanSenate.svg.showingCaesar.png -d 300 /dev/stdin

-d 300 指定输出 DPI。我们使用 /dev/stdin 作为输入文件,因为 InkScape 不处理任何通过管道传输给它的内容。