Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate SVG Image using svg raw data in imagick php

I am trying to create svg image using svg raw data which i am getting from fabric js. I have used below code to generate the svg using svg raw data but its not working properly.

public function generate_svg($raw_svg='',$prefix='',$folder_name='card_image')
{
    $file_name = '';       
    if($raw_svg!='')
    {
        try{           
            $file_name = uniqid($prefix).".svg";
            $image = new \Imagick();
            $image->readImageBlob($raw_svg);
            $image->setImageFormat("svg");
            $image->writeImage($folder_name.$file_name);
        } catch (ImagickException $ex) {
            echo $ex->getMessage();
        }
    }
     return $file_name;
}

Now the issue is background image is kind of Look like below:

enter image description here

So what should i do to fix that?

It should look like below (ignore the square and round), the issue is whole background looks like black instead of bg image.:

enter image description here

So the issue is background image is not loading, so do i have to add additional library to do that or any thing else?

Imagick Version: 6.7.7

    convert -list delegate | grep svg  

    cdr =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    cgm =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    dot =>          "dot' -Tsvg '%i' -o '%o"
    dxf =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    fig =>          "uniconvertor' '%i' '%o.svg'; /bin/mv '%o.svg' '%o"
    svg =>          "rsvg-convert' -o '%o' '%i"

 convert -list format | grep SVG

 MSVG  rw+   ImageMagick's own SVG internal renderer
  SVG  rw+   Scalable Vector Graphics (XML 2.9.1)
 SVGZ  rw+   Compressed Scalable Vector Graphics (XML 2.9.1)
like image 542
DS9 Avatar asked Oct 29 '22 22:10

DS9


2 Answers

I think you are on the wrong track. Image Magick is basically a pixel-oriented library. While rendering the background image might be a question of configuration, your picture shows that the font "embedding" you wanted to achieve isn't happening. And there lies the real problem.

What you want to achieve is representing the font information inside the SVG file. There are two ways to do that, and for both there is absolutely no support in IM:

  • converting the font to the SVG font format and embedding it inline in the file (produces large files)
  • converting all glyphs to paths (texts are no longer editable)

From your description I think you should be aiming for the second variant. You would basically exchange <text> elements in your string with <path> elements and otherwise write out the SVG file including the embeded image data as you received it.

How to convert text to SVG paths? is an older look at that problem.

EasySVG for PHP is a library that resulted from that question for the glyph-to-path conversion, but only provided you have the font already in SVG format. For typical desktop font formats like ttf, you might first have to look at font conversion tools like FontForge.

You might get a direct svg data transformation working via Cairo, but that is only a hunch, I haven't worked with it.

Finally, as a workaround, you could delegate the whole task to Inkscape. It can be called on the command line without starting the GUI as

inkscape in.svg --export-text-to-path --export-plain-svg=out.svg
like image 99
ccprog Avatar answered Nov 13 '22 22:11

ccprog


I have ended up by storing fonts in raw svg and after that created svg file using fopen instead of using imagick.

So my svg is look like below:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="600" height="400" viewBox="0 0 600 400" xml:space="preserve">
<desc>Created with Fabric.js 2.0.0-beta7</desc>
<defs>
<style>
    //... base64 data of font
    @font-face {
        font-family: "Elsie";
        src: url("data:application/font-truetype;charset=utf-8;base64,...")
    }
</style>
</defs>

After that i have created svg file using below:

$file_name = uniqid($prefix).".svg";
$file_handle = fopen("$folder_name/".$file_name, 'w');
fwrite($file_handle, $raw_svg);
fclose($file_handle);
like image 34
DS9 Avatar answered Nov 13 '22 21:11

DS9