Inkscape 有一个这样调用的 shell 模式
inkscape --shell
你可以在哪里执行这样的命令:
some_svg_file.svg -e some_png_output.png -y 1.0 -b #ffffff -D -d 150
这将生成一个 PNG 文件,或者像这样:
/home/simone/some_text.svg -S
它在返回消息中为您提供文件中所有元素的边界框,如下所示
svg2,0.72,-12.834,122.67281,12.942
layer1,0.72,-12.834,122.67281,12.942
text2985,0.72,-12.834,122.67281,12.942
tspan2987,0.72,-12.834,122.67281,12.942
这样做的好处是您可以对 SVG 文件执行操作,而无需每次都重新启动 Inkscape。
我想做这样的事情:
sub do_inkscape {
my ($file, $commands) = @_;
# capture output
return $output
}
如果我像这样使用 open2 和 fork ,一切正常:
use IPC::Open2;
$pid = open2(\*CHLD_OUT, \*CHLD_IN, 'inkscape --shell');
$\ = "\n"; $/ = ">";
my $out; open my $fh, '>', \$out;
if (!defined($kidpid = fork())) {
die "cannot fork: $!";
} elsif ($kidpid == 0) {
while (<>) { print CHLD_IN $_; }
} else {
while (<CHLD_OUT>) { chop; s/\s*$//gmi; print "\"$_\""; }
waitpid($kidpid, 0);
}
但我找不到如何只输入一行,并只捕获该输出而不必每次都重新启动 Inkscape 的方法。
谢谢
西蒙
最佳答案
您不需要 fork ,open2
会自行处理。您需要做的是找到一种检测 inkscape
何时等待输入的方法。
这是一个非常基本的示例,说明如何实现这一点:
#! /usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
sub read_until_prompt($) {
my ($fh) = (@_);
my $done = 0;
while (!$done) {
my $in;
read($fh, $in, 1);
if ($in eq '>') {
$done = 1;
} else {
print $in;
}
}
}
my ($is_in, $is_out);
my $pid = open2($is_out, $is_in, 'inkscape --shell');
read_until_prompt($is_out);
print "ready\n";
print $is_in "test.svg -S\n";
read_until_prompt($is_out);
print $is_in "quit\n";
waitpid $pid, 0;
print "done!\n";
read_until_prompt
从 inkscape
的输出中读取,直到它找到一个 >
字符,并假定当它看到一个时,inkscape
准备好了。
注意:这太简单了,如果 >
可以出现在您期望的输出中的提示之外,您可能需要更多的逻辑才能使其更可靠地工作。上面的脚本中也根本没有错误检查,这很糟糕。
关于perl - 从 perl 使用 Inkscape shell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7695641/