Rendering an Svg File to a Png or Jpeg in PHP

Rendering an SVG file to a PNG or JPEG in PHP

Check if ImageMagick is installed (you can find out using phpinfo). If it is, you can use the following code to cover to a PNG.

$image = new Imagick();
$image->readImageBlob(file_get_contents('image.svg'));
$image->setImageFormat("png24");
$image->resizeImage(1024, 768, imagick::FILTER_LANCZOS, 1);
$image->writeImage('image.png');

There are many threads that discuss this. One that is particularly useful is this thread:
Convert SVG image to PNG with PHP

Convert SVG image to PNG with PHP

That's funny you asked this, I just did this recently for my work's site and I was thinking I should write a tutorial... Here is how to do it with PHP/Imagick, which uses ImageMagick:

$usmap = '/path/to/blank/us-map.svg';
$im = new Imagick();
$svg = file_get_contents($usmap);

/*loop to color each state as needed, something like*/
$idColorArray = array(
"AL" => "339966"
,"AK" => "0099FF"
...
,"WI" => "FF4B00"
,"WY" => "A3609B"
);

foreach($idColorArray as $state => $color){
//Where $color is a RRGGBB hex value
$svg = preg_replace(
'/id="'.$state.'" style="fill:#([0-9a-f]{6})/'
, 'id="'.$state.'" style="fill:#'.$color
, $svg
);
}

$im->readImageBlob($svg);

/*png settings*/
$im->setImageFormat("png24");
$im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1); /*Optional, if you need to resize*/

/*jpeg*/
$im->setImageFormat("jpeg");
$im->adaptiveResizeImage(720, 445); /*Optional, if you need to resize*/

$im->writeImage('/path/to/colored/us-map.png');/*(or .jpg)*/
$im->clear();
$im->destroy();

the steps regex color replacement may vary depending on the svg path xml and how you id & color values are stored. If you don't want to store a file on the server, you can output the image as base 64 like

<?php echo '<img src="data:image/jpg;base64,' . base64_encode($im) . '"  />';?>

(before you use clear/destroy) but ie has issues with PNG as base64 so you'd probably have to output base64 as jpeg

you can see an example here I did for a former employer's sales territory map:

Start: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg

Finish: Sample Image

Edit

Since writing the above, I've come up with 2 improved techniques:

1) instead of a regex loop to change the fill on state , use CSS to make style rules like

<style type="text/css">
#CA,#FL,HI{
fill:blue;
}
#Al, #NY, #NM{
fill:#cc6699;
}
/*etc..*/
</style>

and then you can do a single text replace to inject your css rules into the svg before proceeding with the imagick jpeg/png creation. If the colors don't change, check to make sure you don't have any inline fill styles in your path tags overriding the css.

2) If you don't have to actually create a jpeg/png image file (and don't need to support outdated browsers), you can manipulate the svg directly with jQuery. You can't access the svg paths when embedding the svg using img or object tags, so you'll have to directly include the svg xml in your webpage html like:

<div>
<?php echo file_get_contents('/path/to/blank/us-map.svg');?>
</div>

then changing the colors is as easy as:

<script type="text/javascript" src="/path/to/jquery.js"></script>
<script type="text/javascript">
$('#CA').css('fill', 'blue');
$('#NY').css('fill', '#ff0000');
</script>

How can i convert a svg image to png image with Imagemagick when the svg file has embedded images?

ImageMagick's built-in SVG rendering is really pretty horrible. Don't use it if you can avoid it. I'd recommend using librsvg instead, either using the command-line rsvg tool, or possibly with the PHP rsvg extension.

(Librsvg's rendering isn't always perfect either, but it should be able to handle embedded images just fine. If you want even better rendering, you could always try using Inkscape from the command line.)

Convert SVG to image (JPEG, PNG, etc.) in the browser

Here is how you can do it through JavaScript:

  1. Use the canvg JavaScript library to render the SVG image using Canvas: https://github.com/gabelerner/canvg
  2. Capture a data URI encoded as a JPG (or PNG) from the Canvas, according to these instructions: Capture HTML Canvas as gif/jpg/png/pdf?

Unable to read image from file .SVG (intervention/image)

So with further experimentation and trying to get something to work with staying to the intervention/image library but without converting the svg to anything I've gone with the following solution:

public function dropzoneStore(Request $request){
$image = $request->file('file');
$imageName = date("dHis-").preg_replace("/[^a-zA-Z0-9.]/","",$image->getClientOriginalName());
$uploadPath = public_path('up/').date("Y/m");
$image->move($uploadPath,$imageName);
//Thumbnail Creation
$thumbPath = $uploadPath.'/thumbs/';
File::isDirectory($thumbPath) or File::makeDirectory($thumbPath,0775,true,true);
if($image->getClientOriginalExtension() != 'svg'){
$imageThmb = Image::make($uploadPath.'/'.$imageName);
$imageThmb->fit(300,300,function($constraint){$constraint->upsize();})->save($uploadPath.'/thumbs/thm_'.$imageName,80);
}else{
File::copy($uploadPath.'/'.$imageName,$uploadPath.'/thumbs/thm_'.$imageName);
}
return response()->json(['success'=>$imageName]);
}

Which while a bit far fetched and a hacky approach in my eyes, still does seem to do the trick to work alongside with my file system that requires a thumb for every image.

While I might look into it anyway when I further expand the use of my website to eventually do convert the SVG images to thumbnails. But for now this will do and as .svg's aren't that used yet for website development I can be at ease as well in terms of load.

Either way I thank everyone who tried to assist me with this matter!

PHP Convert SVG To Jpg Missing Elements

Finally I found a workaround for this. I converted svg to canvas image (base64 format) via javascript and through php i have converted the base64 data to jpg image.



Related Topics



Leave a reply



Submit