Reputation: 10772
I'm having an issue with custom fonts not rendering when attempting to convert an SVG to a JPG image. I am using font-family="Lobster"
defined for an SVG text element.
My server setup is as follows:
The PHP code I am testing with, but does not work. I am attempting to use the custom font Lobster.
//Setup SVG to be read by Imagick.
$SVG = '<?xml version="1.0" encoding="utf-8"?>';
$SVG .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
$SVG .= '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="158px" height="92px" viewBox="0 0 158 92" enable-background="new 0 0 158 92" xml:space="preserve">';
$SVG .= '<text transform="matrix(1 0 0 1 32 58)" font-family="Lobster" font-style="normal" font-size="20px" font-weight="400">Lobster</text>';
$SVG .= '</svg>';
$image = new Imagick();
//Convert SVG to JPG
$image->readImageBlob($SVG);
$image->setImageFormat("jpeg");
//Save the thumbnail.
$save_path = '/home/username/lobster.jpg';
$image->writeImage($save_path);
echo '<img src="lobster.jpg" alt="" /><br />';
Which produces the following image:
I've created a type.xml file located at /home/username/.magick/type.xml
with the Lobster font definition as shown here:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE typemap [
<!ELEMENT typemap (type)+>
<!ELEMENT type (#PCDATA)>
<!ELEMENT include (#PCDATA)>
<!ATTLIST type name CDATA #REQUIRED>
<!ATTLIST type fullname CDATA #IMPLIED>
<!ATTLIST type family CDATA #IMPLIED>
<!ATTLIST type foundry CDATA #IMPLIED>
<!ATTLIST type weight CDATA #IMPLIED>
<!ATTLIST type style CDATA #IMPLIED>
<!ATTLIST type stretch CDATA #IMPLIED>
<!ATTLIST type format CDATA #IMPLIED>
<!ATTLIST type metrics CDATA #IMPLIED>
<!ATTLIST type glyphs CDATA #REQUIRED>
<!ATTLIST type version CDATA #IMPLIED>
<!ATTLIST include file CDATA #REQUIRED>
]>
<typemap>
<type
format="ttf"
name="Lobster"
fullname="Lobster"
family="Lobster"
glyphs="/home/username/fonts/Lobster/Lobster.ttf"
style="normal"
stretch="normal"
weight="400"
/>
</typemap>
I've included a direct include in the /usr/lib/ImageMagick-6.5.4/config/type.xml
file like this:
<typemap>
<include file="type-ghostscript.xml" />
<include file="/home/username/.magick/type.xml" />
</typemap>
When outputting the fonts using the $image->queryfonts();
method, I can see the Lobster font defined in the list. For example, this:
$image = new Imagick();
$fonts = $image->queryfonts();
foreach($fonts as $font) {
echo $font . '<br />';
}
Returns this:
[...]
Hershey-Plain-Triplex-Regular
Hershey-Script-Complex-Regular
Hershey-Script-Simplex-Regular
Lobster
MeriendaOne
NewCenturySchlbk-Bold
NewCenturySchlbk-BoldItalic
NewCenturySchlbk-Italic
NewCenturySchlbk-Roman
[...etc]
Additionally, I believe ImageMagick is using it's own internal SVG renderer. The shell command:
convert -list format | grep SVG
Returns:
MSVG SVG rw+ ImageMagick's own SVG internal renderer
SVG SVG rw+ Scalable Vector Graphics (RSVG 2.26.0)
SVGZ SVG rw+ Compressed Scalable Vector Graphics (RSVG 2.26.0)
Any ideas as to why this isn't working?
Upvotes: 5
Views: 2619
Reputation: 433
I was having the same problem converting SVG to PNG using Imagemagick but was unable to make it work using that approach. I was somehow able to get the result I need using docraptor:
DocRaptor.createAndDownloadDoc("YOUR_API_KEY", {
test: true, // test documents are free, but watermarked
type: "pdf",
document_content: document.getElementById('container_of_svg').innerHTML
})
Just make sure to add the font declarations inside the container_of_svg element like below and make sure to add an absolute URL to your fonts:
@font-face {
font-family: 'DaimlerCS-Demi';
src: url("https://staging.xxx.com/xx/fonts/xx/FontCS-Demi.eot")
}
page {
size: 21.16cm 15.87cm;
padding: 1cm;
margin:0;
background: #E6E6E6;
}
Just check their document here: https://docraptor.com/documentation/jquery
Note: docraptor is not free but if your client can pay for it, I think its a solid option.
Upvotes: 1
Reputation: 25711
Please restart your webserver, or PHP-FPM instances.
Apparently the information about which fonts can be used in an SVG is cached by ImageMagick, even though the list returned by queryFonts() isn't cached.
Your code example didn't work for me until I restarted my php-fpm instance, and then it worked perfectly.
Upvotes: 0