Search code examples
phpimage-processingsvgimagemagickimagick

Imagick can't write SVG files


I use Imagick to open an image, resize it, set an image format (if it's needed) and write in another folder the result. It works with ICO and PNG, but can't write SVG files, saying that

ImagickException: Unable to write the file: C:\Sites\devdesktop\test\sites\default\files\tempimages\abstract-spiral-striped-background-100.svg in Imagick->writeimage() (line 44 of C:\Sites\devdesktop\test\sites\all\modules\testmodule\testmodule.module).

It was an error message from Drupal 7.

Here is my code:

$file = file_load($form_state['values']['fid']);
$image = new Imagick(drupal_realpath($file->uri));
$image->setImageFormat($type[$type_num]);
$image->resizeImage($size[$size_num], $size[$size_num], Imagick::FILTER_UNDEFINED, 1);
$destination = 'public://tempimages/'.substr($file->filename, 0, -4).'-'.$size[$size_num].'.'.$type[$type_num];
$image->writeImage(drupal_realpath($destination));    //<---problem
drupal_goto(base_path().'/sites/default/files/tempimages/'.substr($file->filename, 0, -4).'-'.$size[$size_num].'.'.$type[$type_num]);

This code snippet works perfectly with ICO and PNG, but don't write a file in SVG format except a little peace of code

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="200" height="200">
<g style="</svg> 

Why so?


Solution

  • SVG isn't an image in the same way that JPG or PNG are.

    It's just an xml with plotted points in most cases, and is typically void of dimension and resolution.

    The width and height of 200 are just the size in px at which it was saved. So you should never need to 'resize' an svg, as it will scale infinitely.

    If you put an SVG in an img tag and define the dimensions, like:

    <img src="myawesome.svg" width="500" height="500" />

    Even though it's defined in the SVG as having a dimensions of 200, it should scale larger or smaller with no change in the quality of appearance.

    Because of this complete difference in structure, it will not follow the same rules in some cases as jpg or png will as they are rendered images.

    If this is being done in Drupal; make an exception for SVG that just stores the file without resizing, and add the dimensions where ever it is printed for all images. It won't hurt the rendered images, and it should show the SVG as the same size as them.

    TL;DR SVG is an xml file, not really an image, resizing it is pointless since it carries no real resolution or size and can scale infinitely. They only appear to be similar since they are both visual elements. Make an exception for SVG so it just stores the file, and when either the rendered images or the SVG is printed, add the resized dimensions to the img output.