我已经编写了一个脚本,用于将SVG转换为PNG,该脚本工作得非常好,直到SVG中的内容出现在页面外的#34;。
例如:
黑线将被正确转换,但绿框完全被忽略。某些SVG文件的内容完全在页面外,并呈现一个空的PNG文件。
我目前的命令:
convert -background none "$file" -trim -geometry $size "$target"
我有2k + SVG文件我正在使用此问题转换至少约500或更多,因此手动将图像移动到页面上并不是一个选项。
修改 这是example file的链接。实际绘图与左侧页面底部一致。
答案 0 :(得分:0)
当然在PNG中将忽略'off off'的内容。与SVG不同,PNG文件格式不知道“离页”概念。
这类似于在一张纸上打印:打印机也无法显示“关闭页面”内容。
您可以通过两种方式进行探索。两者的结果是您将实际页面大小更改为更大的页面大小:
您可能能够通过将SVG渲染到更大的PNG画布来获取PNG中的“off page”内容,之后 自动修剪多余的边缘。 (由于缺少样本文件,我不能自己尝试。)
您可以尝试在2个或3个步骤中获得所需的结果:
答案 1 :(得分:0)
所以我终于有了这个工作。似乎无法直接使用ImageMagick进行操作,因此最终操纵了实际的SVG数据。
首先要找到对象的边界。使用PHP和simpleXml我将SVG数据转换为数组以便于操作/遍历。
似乎所有坐标都是x y的形式,所以这会将坐标分解为数字,并在x / y记录之间切换,如果它高于/低于之前的值。
/** $line is a <g> object */
protected function _position($line, &$position) {
if(empty($line['@d'])) {
if(is_array($line)) {
foreach($line as $l) {
self::_position($l, $position);
}
return;
}
}
if(empty($position)) {
$position = array(
'min' => array(
'x' => null,
'y' => null
),
'max' => array(
'x' => null,
'y' => null
)
);
}
foreach(array_filter(preg_split('/([a-z])/i', $line['@d'])) as $cord) {
$coordinate = 'x';
foreach(explode(' ', $cord) as $value) {
if(empty($value)) {
continue;
}
if($position['min'][$coordinate] == null || $position['min'][$coordinate] > $value - 1) {
$position['min'][$coordinate] = $value;
}
if($position['max'][$coordinate] == null || $position['max'][$coordinate] < $value + 1) {
$position['max'][$coordinate] = $value;
}
$coordinate = ($coordinate != 'x') ? 'x' : 'y';
}
}
}
一旦你得到了最小/最大界限,我找到了一个带有transform
的属性translate
,它通过指定的x,y移动一个对象。所以只需0 - $min
,它就会移到0
,因为它可能是0 - -10
或0 - 10
我的所有文件都没有属性,所以我只是用<g>
<g transform="translate($widthOffset, $heightOffset)">
同时设置视图框大小:
$xml['svg']['@viewbox'] = sprintf('%s %s %s %s',
$position['min']['x'],
$position['min']['y'],
($position['max']['x'] - $position['min']['x']),
($position['max']['y'] - $position['min']['y'])
);
最后要做的就是将数组转换回XML并将新数据保存回文件中。