So I finally got this working. Could not seem to do it with ImageMagick directly so ended up manipulating the actual SVG data.
First thing is to find the bounds of the object. Using PHP and simpleXml I converted the SVG data to an array for easy manipulation / traversing.
It seems like all the coordinates are in the form of x y so this breaks the coordinates up into numbers and switches between x / y recording if its higher/lower than the previous values.
/** $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';
}
}
}
Once you got the min/max bounds I found a property transform
with translate
which moves an object by the x,y specified. So just take 0 - $min
and it will be moved to 0
as it could be 0 - -10
or 0 - 10
All my files have with no attributes so I just done a simple replace of <g>
with <g transform="translate($widthOffset, $heightOffset)">
Also set the viewbox size:
$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'])
);
Last thing to do is just convert the array back to XML and save the new data back into the file.