как изменить размер SVG с помощью Imagick/ImageMagick

Я отправляю строковое представление SVG-файла на сервер и использую Imagick, чтобы преобразовать его в jpeg следующим образом:

$image = stripslashes($_POST['json']);
$filename = $_POST['filename'];
$unique = time();

$im = new Imagick();
$im->readImageBlob($image);
$im->setImageFormat("jpeg");
$im->writeImage('../photos/'. $type. '/humourised_'. $unique. $filename);
$im->clear();
$im->destroy();

Однако я хочу изменить размер SVG перед его растрированием, чтобы результирующее изображение было больше, чем размеры, указанные в файле SVG.

Я изменил свой код на следующий:

$image = stripslashes($_POST['json']);
$filename = $_POST['filename'];
$unique = time();

$im = new Imagick();
$im->readImageBlob($image);
$res = $im->getImageResolution();
$x_ratio = $res['x'] / $im->getImageWidth();
$y_ratio = $res['y'] / $im->getImageHeight();
$im->removeImage();
$im->setResolution($width_in_pixels * $x_ratio, $height_in_pixels * $y_ratio);

$im->readImageBlob($image);
$im->setImageFormat("jpeg");
$im->writeImage('../photos/'. $type. '/humourised_'. $unique. $filename);
$im->clear();
$im->destroy();

Этот код должен работать с разрешением и соответствующим образом изменять размер SVG. Он отлично работает, если холст SVG и его элементы имеют ширину в процентах, однако он не работает с элементами, определенными в «px». Что, к сожалению, является требованием.

Типичная строка SVG, которая будет отправлена ​​на сервер, выглядит следующим образом.:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/SVG/DTD/svg10.dtd">
<svg id="tempsvg" style="overflow: hidden; position: relative;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="333" version="1.1" height="444">
   <image transform="matrix(1,0,0,1,0,0)" preserveAspectRatio="none" x="0" y="0" width="333" height="444" xlink:href="http://www.songbanc.com/assets/embed/photos/full/133578615720079914224f9e7aad9ac871.jpg"></image>
   <image transform="matrix(1,0,0,1,0,0)" preserveAspectRatio="none" x="85.5" y="114" width="50" height="38" xlink:href="http://www.songbanc.com/assets/embed/humourise/elements/thumb/thumb_lips4.png"></image>
   <path transform="matrix(1,0,0,1,0,0)" fill="none" stroke="#000" d="M110.5,133L140.5,133" stroke-dasharray="- " opacity="0.5"></path>
   <circle transform="matrix(1,0,0,1,0,0)" cx="140.5" cy="133" r="5" fill="#000" stroke="#000"></circle>
   <path transform="matrix(1,0,0,1,0,0)" fill="none" stroke="#000" d="M110.5,133L110.5,155.8" stroke-dasharray="- " opacity="0.5"></path>
   <circle transform="matrix(1,0,0,1,0,0)" cx="110.5" cy="155.8" r="5" fill="#000" stroke="#000"></circle>
   <circle transform="matrix(1,0,0,1,0,0)" cx="110.5" cy="133" r="5" fill="#000" stroke="#000"></circle>
</svg>

Как вы можете видеть, элементы, составляющие этот SVG, имеют ширину и высоту в пикселях (использование процентов, к сожалению, не подходит для этого приложения.)

Есть ли способ обойти это? Или любой другой метод преобразования SVG в png и рендеринга его в заданном размере без потери качества.

Спасибо.

РЕДАКТИРОВАТЬ :Хотя мне так и не удалось найти идеальное решение. Вместо этого я закончил отправлять данные SVG в виде json, перебирая их на стороне сервера и масштабируя пиксели до предполагаемой высоты.

Затем, после долгих проб и ошибок, я понял, что у imagemagick были проблемы со стандартными командами преобразования/поворота SVG, выбрасывающими любые манипулируемые элементы из строя. В итоге я переключился на «inkscape», чтобы отобразить полученный SVG в виде растрового изображения. И все хорошо. Я все еще ищу потенциальное формальное решение, чтобы компенсировать различия, которые делает imagemagick. Если я добьюсь успеха, я снова обновлю этот вопрос.

12
задан gordyr 1 May 2012 в 20:32
поделиться