Centos Imagick readImage for SVG seems to ignore delegates.xml

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
neekfenwick
Posts: 10
Joined: 2018-08-11T21:56:10-07:00
Authentication code: 1152

Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by neekfenwick » 2018-12-20T21:03:08-07:00

Hi all,

I find that even if I corrupt the 'svg' delegates.xml line, so that the delegate binary should not be found, the conversion still happens (badly). I would like to know how to find what my system is using to perform the SVG conversion.

Code: Select all

# convert -version
Version: ImageMagick 6.9.10-16 Q16 x86_64 2018-12-11 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib cairo djvu fftw fontconfig freetype gslib gvc jbig jng jp2 jpeg lcms ltdl lzma openexr pangocairo png ps raw rsvg tiff webp wmf x xml zlib

# rpm -qa | grep -i imagemagick
ImageMagick6-libs-6.9.10.16-1.el7.remi.x86_64
ImageMagick6-6.9.10.16-1.el7.remi.x86_64
ImageMagick6-devel-6.9.10.16-1.el7.remi.x86_64
I find that converting an SVG to bitmap results in 1 out of 3 paths with a pattern filled with an image results in a black area, instead of the image fill. Compiling and using the latest rsvg-convert utility gives a good result. I'm trying to investigate what my system is actually using to do the conversion.

PHP code:

Code: Select all

$masterSVGFilename = 'some_file.svg';
$im->readImage($masterSVGFilename);
$im->setImageFormat('jpg');
$im->resizeImage($widthPx, $heightPx, imagick::FILTER_LANCZOS, 1);
$im->writeImage($outFilename);
I have read a lot of posts, and I think the conversion should be done using, in order of priority:
1/ inkscape if it is installed (from what I have read this is hardcoded and cannot be controlled), or
2/ one of the delegates available

I have uninstalled inkscape from the system, leaving only the delegates option. I have only one delegates.xml file on disk.

Code: Select all

# locate delegates.xml
/etc/ImageMagick6/ImageMagick-6/delegates.xml
This delegates.xml has two lines to do with 'svg', there is no rsvg or msvg mentioned.

Code: Select all

# grep -i svg /etc/ImageMagick6/ImageMagick-6/delegates.xml
  <delegate decode="svg" command="&quot;rsvg-convert&quot; -o &quot;%o&quot; &quot;%i&quot;"/>
  <delegate decode="svg:decode" stealth="True" command="&quot;inkscape&quot; &quot;%s&quot; --export-png=&quot;%s&quot; --export-dpi=&quot;%s&quot; --export-background=&quot;%s&quot; --export-background-opacity=&quot;%s&quot; &gt; &quot;%s&quot; 2&gt;&amp;1"/>
If I corrupt the 'svg' line so that it has 'rsvgxxx-convert', and restart httpd and php-fpm to make sure changes are reloaded, my PHP code still functions. I have no idea what it is using to do the conversion. Could it be falling back to an internal MSVG method?

If it _is_ using MSVG, then how do I force it to use the 'svg' delegate named in delegates.xml? I have tried prefixing the filename with 'svg:':

Code: Select all

$im->readImage('svg:' . $masterSVGFilename);
This does run, but still the output image is wrong, and I would expect the call to fail because the 'svg' delegate in delegates.xml has been explicitly corrupted.

So, how can I examine the operation being performed by Imagick to load this SVG file?

(I have resorted to using exec() to run rsvg-convert manually, and compiled rsvg-convert from source because the version on my system is librsvg2-tools-2.40.20-1.el7.x86_64 and https://github.com/ImageMagick/librsvg/ says "You are looking at the 2.40.x series in librsvg, which is implemented in the C programming language. This release series is no longer maintained!" and leads me to https://gitlab.gnome.org/GNOME/librsvg where I have compiled with 'autogen.sh --exec-prefix=/usr/local' to get me 2.44.11 which does a good conversion.. but now I cannot make Imagick use that version because of the above trouble with delegates.xml)

neekfenwick
Posts: 10
Joined: 2018-08-11T21:56:10-07:00
Authentication code: 1152

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by neekfenwick » 2018-12-20T21:05:51-07:00

P.S. Perhaps "Delegates (built-in): [cut] rsvg" indicates that the rsvg delegate is built-in, and as I have found, older versions of rsvg do a poor job of converting my SVG with image pattern fills. So my original question still stands, how do I show exactly what method Imagick is using to do the conversion (to prove it is using the built-in rsvg delegate).

Then I guess the question is, how do I show the version of rsvg that is built in, and can I force Imagick to use a different delegate, given that my attempt to specify "svg:" prefix to force use of a delegate named in delegates.xml failed?

User avatar
fmw42
Posts: 25581
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by fmw42 » 2018-12-20T21:11:06-07:00

It is not accurate. If Inkscape is on your system, then it will be used. Otherwise, check

Code: Select all

convert -list format
and look for line starting with Delegates. It will say either RSVG if you have librsvg installed or MSVG or XML for the internal ImageMagick renderer.

However the best way is to just add -verbose to your command line and see which renderer is shown doing the processing.

neekfenwick
Posts: 10
Joined: 2018-08-11T21:56:10-07:00
Authentication code: 1152

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by neekfenwick » 2018-12-21T02:49:55-07:00

Good call fmw42, I should have listed that in my original post.

Code: Select all

$ convert -list format | grep -i svg
     MSVG  SVG       rw+   ImageMagick's own SVG internal renderer
      SVG  SVG       rw+   Scalable Vector Graphics (RSVG 2.40.16)
     SVGZ  SVG       rw+   Compressed Scalable Vector Graphics (RSVG 2.40.16)
So the built-in RSVG delegate seems to be 2.40.16, the obsolete one that doesn't work. I have installed 2.44.11 on my system which performs well when I exec it instead of using Imagick, now I'm back to the question of why delegates.xml doesn't seem to do anything.

I tried inventing a new delegate.xml line:

Code: Select all

  <delegate decode="blah" command="&quot;/usr/local/bin/rsvg-convert&quot; -o &quot;%o&quot; &quot;%i&quot;"/>
and loading the SVG file with:

Code: Select all

$im->readImage('blah:' . $masterSVGFilename);
This does load the image but doesn't handle the patterns correctly, so it seems like it's using the wrong delegate despite accepting the 'blah:' prefix with no complaint (nothing appearing in error_log to indicate a problem).

neekfenwick
Posts: 10
Joined: 2018-08-11T21:56:10-07:00
Authentication code: 1152

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by neekfenwick » 2018-12-21T02:54:51-07:00

FYI, as you might expect, with my new 'blah' entry in delegates.xml I also cannot make command line 'convert' use it, i.e.:

Code: Select all

$ convert blah:master.svg out.png
Gives blank image patterns.

Code: Select all

$ /usr/local/bin/rsvg-convert master.svg -o out.png
Gives good looking image patterns.

So it seems as much a problem with the command line convert as it is with the Imagick PHP bindings.

User avatar
fmw42
Posts: 25581
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by fmw42 » 2018-12-21T10:44:40-07:00

Sorry, if I misunderstand, but did you install RSVG 2.44.11 as a delegate to Imageamagick? If so, does it now show in your list of

Code: Select all

convert -list format
If not, then you need to re-install ImageMagick so that it can find it and shows as your SVG delegate

If it shows, then you might check to see that you do not have Inkscape on your system, which will take precedence.

The best way to find out what is going on is to put -verbose in your command line and see which delegate is being used.

Code: Select all

convert -verbose master.svg out.png

snibgo
Posts: 12169
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by snibgo » 2018-12-21T10:55:13-07:00

neekfenwick wrote:FYI, as you might expect, with my new 'blah' entry in delegates.xml I also cannot make command line 'convert' use it, i.e.:

Code: Select all

$ convert blah:master.svg out.png
Then something is wrong. Your "blah" entry should be used. What is the output from a "-verbose" in that convert?

"-debug all" will tell you what delegates.xml files are being read.

What does "convert -list delegate" say? It should contain a line like:

Code: Select all

blah =>          "rsvg-convert" -o "%o" "%i"
... but ensure your delegates.xml entries don't contain [tt]stealth="True"[/tt].
snibgo's IM pages: im.snibgo.com

neekfenwick
Posts: 10
Joined: 2018-08-11T21:56:10-07:00
Authentication code: 1152

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by neekfenwick » 2018-12-21T20:46:50-07:00

Thanks for all the responses! You've reminded me of the '-verbose' command line switch which of course shows exactly how 'convert' is doing the conversion, and it led me to some conclusions. I had thought delegates.xml wasn't being used because I saw differences in the 'convert' output to the raw 'rsvg-convert' output, but it turns out the rsvg-convert delegate _was_ being used, but it behaves differently when run from 'convert' to when it's run on its own.

- I can use 'strace' to watch what's going on as rsvg-convert does its work via 'convert', with the -f switch to trace child processes: strace -f -- convert blah:master.svg -o out.png

Code: Select all

[pid 10003] lstat("/tmp/frame1_cactus-cropped-thumb.jpg", {st_mode=S_IFREG|0644, st_size=51331, ...}) = 0
[pid 10003] open("/tmp/frame1_cactus-cropped-thumb.jpg", O_RDONLY) = 5
This proved that rsvg-convert was looking for the image specified as href="frame1_cactus-cropped-thumb.jpg" in the /tmp directory, where it was not.

- This reminded me, when run via 'convert' command line, your SVG file is copied to the temp dir (/tmp in my case), so any relative paths become relative to /tmp and not the original working directory.

Code: Select all

write(2, "'/usr/local/bin/rsvg-convert' -o"..., 97'/usr/local/bin/rsvg-convert' -o '/tmp/magick-11828qRgZ_-dQs8jk' '/tmp/magick-11828vX-i7ClrNPoA'
) = 97
So, of course my relative paths like "thing.jpg" were not found. If I copy thing.jpg to /tmp first, then run convert, the image shows up in the output png (yay!).

- via 'convert', absolute file:// URLs in pattern fills do work when specifying the temp directory location, e.g. <pattern ...><image xlink:href="file:///tmp/frame1_cactus-cropped-thumb.jpg" ... ></pattern> (this gave the strace output above)

Code: Select all

[pid 12165] lstat("/tmp/frame1_cactus-cropped-thumb.jpg", {st_mode=S_IFREG|0644, st_size=51331, ...}) = 0
[pid 12165] open("/tmp/frame1_cactus-cropped-thumb.jpg", O_RDONLY) = 5
[pid 12165] fstat(5, {st_mode=S_IFREG|0644, st_size=51331, ...}) = 0
[pid 12165] read(5, "\377\330\377\340\0\20JFIF\0\1\1\1\0H\0H\0\0\377\376\0\23Created "..., 51331) = 51331
[pid 12165] close(5)                    = 0
- via 'convert', absolute file:// URLs to the working dir (in a user directory web root) do not work, e.g. <pattern ...><image xlink:href="file:///home/username/public_html/path_here/frame1_cactus-cropped-thumb.jpg" ... ></pattern>

Code: Select all

[pid 10377] lstat("/home/username/public_html/path_here/frame2_cake-cropped-thumb.jpg", {st_mode=S_IFREG|0644, st_size=46294, ...}) = 0
- at the same time, via 'rsvg-convert' directly, file:// URLS specifying the tmp dir DO NOT work! This seems pretty crazy to me, when it worked when invoked from 'convert'.
e.g. <pattern ...><image xlink:href="file:///tmp/frame1_cactus-cropped-thumb.jpg" ... ></pattern> gives strace output:

Code: Select all

lstat("/tmp/frame1_cactus-cropped-thumb.jpg", {st_mode=S_IFREG|0644, st_size=51331, ...}) = 0
read(4, "", 4096)      
[cut...]
close(4)
So rsvg-convert fails to read any bytes from a file in /tmp when run on its own. All these files are world readable, there is no chroot jailing going on, I'm at a bit of a loss to say what's going wrong.

I'll leave some more investigation below here, and stick to using exec() to run rsvg-convert directly with simple relative paths in the SVG, which is still working well.

Code: Select all

$ convert -list format
   Format  Module    Mode  Description
-------------------------------------------------------------------------------
      3FR  DNG       r--   Hasselblad CFV/H3D39II
      3G2  MPEG      r--   Media Container
      3GP  MPEG      r--   Media Container
      AAI* AAI       rw+   AAI Dune image
       AI  PDF       rw-   Adobe Illustrator CS2
      ART* ART       rw-   PFS: 1st Publisher Clip Art
      ARW  DNG       r--   Sony Alpha Raw Image Format
      AVI  MPEG      r--   Microsoft Audio/Visual Interleaved
      AVS* AVS       rw+   AVS X image
      BGR* BGR       rw+   Raw blue, green, and red samples
     BGRA* BGR       rw+   Raw blue, green, red, and alpha samples
     BGRO* BGR       rw+   Raw blue, green, red, and opacity samples
      BIE* JBIG      rw-   Joint Bi-level Image experts Group interchange format (2.0)
      BMP* BMP       rw-   Microsoft Windows bitmap image
     BMP2* BMP       rw-   Microsoft Windows bitmap image (V2)
     BMP3* BMP       rw-   Microsoft Windows bitmap image (V3)
      BRF* BRAILLE   -w-   BRF ASCII Braille format
      CAL* CALS      rw-   Continuous Acquisition and Life-cycle Support Type 1
           Specified in MIL-R-28002 and MIL-PRF-28002
     CALS* CALS      rw-   Continuous Acquisition and Life-cycle Support Type 1
           Specified in MIL-R-28002 and MIL-PRF-28002
   CANVAS* XC        r--   Constant image uniform color
  CAPTION* CAPTION   r--   Caption
      CIN* CIN       rw-   Cineon Image File
      CIP* CIP       -w-   Cisco IP phone image format
     CLIP* CLIP      rw+   Image Clip Mask
     CMYK* CMYK      rw+   Raw cyan, magenta, yellow, and black samples
    CMYKA* CMYK      rw+   Raw cyan, magenta, yellow, black, and alpha samples
      CR2  DNG       r--   Canon Digital Camera Raw Image Format
      CRW  DNG       r--   Canon Digital Camera Raw Image Format
      CUR* ICON      rw-   Microsoft icon
      CUT* CUT       r--   DR Halo
     DATA* INLINE    rw+   Base64-encoded inline images
      DCM* DCM       r--   Digital Imaging and Communications in Medicine image
           DICOM is used by the medical community for images like X-rays.  The
           specification, "Digital Imaging and Communications in Medicine
           (DICOM)", is available at http://medical.nema.org/.  In particular,
           see part 5 which describes the image encoding (RLE, JPEG, JPEG-LS),
           and supplement 61 which adds JPEG-2000 encoding.
      DCR  DNG       r--   Kodak Digital Camera Raw Image File
      DCX* PCX       rw+   ZSoft IBM PC multi-page Paintbrush
      DDS* DDS       rw+   Microsoft DirectDraw Surface
    DFONT* TTF       r--   Multi-face font package (Freetype 2.4.11)
      DNG  DNG       r--   Digital Negative
      DOT  DOT       r--   Graphviz
      DPX* DPX       rw-   SMPTE 268M-2003 (DPX 2.0)
           Digital Moving Picture Exchange Bitmap, Version 2.0.
           See SMPTE 268M-2003 specification at http://www.smtpe.org
           
     DXT1* DDS       rw+   Microsoft DirectDraw Surface
     DXT5* DDS       rw+   Microsoft DirectDraw Surface
     EPDF  PDF       rw-   Encapsulated Portable Document Format
      EPI  PS        rw-   Encapsulated PostScript Interchange format
      EPS  PS        rw-   Encapsulated PostScript
     EPS2  PS2       -w-   Level II Encapsulated PostScript
     EPS3  PS3       -w+   Level III Encapsulated PostScript
     EPSF  PS        rw-   Encapsulated PostScript
     EPSI  PS        rw-   Encapsulated PostScript Interchange format
      EPT  EPT       rw-   Encapsulated PostScript with TIFF preview
     EPT2  EPT       rw-   Encapsulated PostScript Level II with TIFF preview
     EPT3  EPT       rw+   Encapsulated PostScript Level III with TIFF preview
      ERF  DNG       r--   Epson Raw Format
      EXR  EXR       rw-   High Dynamic-range (HDR)
      FAX* FAX       rw+   Group 3 FAX
           FAX machines use non-square pixels which are 1.5 times wider than
           they are tall but computer displays use square pixels, therefore
           FAX images may appear to be narrow unless they are explicitly
           resized using a geometry of "150x100%".
           
     FILE* URL       r--   Uniform Resource Locator (file://)
     FITS* FITS      rw-   Flexible Image Transport System
  FRACTAL* PLASMA    r--   Plasma fractal image
      FTP* URL       r--   Uniform Resource Locator (ftp://)
      FTS* FITS      rw-   Flexible Image Transport System
       G3* FAX       rw-   Group 3 FAX
       G4* FAX       rw-   Group 4 FAX
      GIF* GIF       rw+   CompuServe graphics interchange format
    GIF87* GIF       rw-   CompuServe graphics interchange format (version 87a)
 GRADIENT* GRADIENT  r--   Gradual linear passing from one shade to another
     GRAY* GRAY      rw+   Raw gray samples
    GRAYA* GRAY      rw+   Raw gray and alpha samples
   GROUP4* TIFF      rw-   Raw CCITT Group4
       GV  DOT       r--   Graphviz
        H* MAGICK    -w-   Image expressed as a 'C/C++' char array
     HALD* HALD      r--   Identity Hald color lookup table image
      HDR* HDR       rw+   Radiance RGBE image format
HISTOGRAM* HISTOGRAM -w-   Histogram of the image
      HRZ* HRZ       rw-   Slow Scan TeleVision
      HTM* HTML      -w-   Hypertext Markup Language and a client-side image map
     HTML* HTML      -w-   Hypertext Markup Language and a client-side image map
     HTTP* URL       r--   Uniform Resource Locator (http://)
    HTTPS* URL       ---   Uniform Resource Locator (https://)
      ICB* TGA       rw-   Truevision Targa image
      ICO* ICON      rw+   Microsoft icon
     ICON* ICON      rw-   Microsoft icon
      IIQ  DNG       r--   Phase One Raw Image Format
     INFO  INFO      -w+   The image format and characteristics
   INLINE* INLINE    rw+   Base64-encoded inline images
      IPL* IPL       rw+   IPL Image Sequence
   ISOBRL* BRAILLE   -w-   ISO/TR 11548-1 format
  ISOBRL6* BRAILLE   -w-   ISO/TR 11548-1 format 6dot
      J2C* JP2       rw-   JPEG-2000 Code Stream Syntax (2.3.0)
      J2K* JP2       rw-   JPEG-2000 Code Stream Syntax (2.3.0)
      JBG* JBIG      rw+   Joint Bi-level Image experts Group interchange format (2.0)
     JBIG* JBIG      rw+   Joint Bi-level Image experts Group interchange format (2.0)
      JNG* PNG       rw-   JPEG Network Graphics
           See http://www.libpng.org/pub/mng/ for details about the JNG
           format.
      JNX* JNX       r--   Garmin tile format
      JP2* JP2       rw-   JPEG-2000 File Format Syntax (2.3.0)
      JPC* JP2       rw-   JPEG-2000 Code Stream Syntax (2.3.0)
      JPE* JPEG      rw-   Joint Photographic Experts Group JFIF format (libjpeg-turbo 1.2.90)
     JPEG* JPEG      rw-   Joint Photographic Experts Group JFIF format (libjpeg-turbo 1.2.90)
      JPG* JPEG      rw-   Joint Photographic Experts Group JFIF format (libjpeg-turbo 1.2.90)
      JPM* JP2       rw-   JPEG-2000 Code Stream Syntax (2.3.0)
      JPS* JPEG      rw-   Joint Photographic Experts Group JFIF format (libjpeg-turbo 1.2.90)
      JPT* JP2       rw-   JPEG-2000 File Format Syntax (2.3.0)
     JSON  JSON      -w+   The image format and characteristics
      K25  DNG       r--   Kodak Digital Camera Raw Image Format
      KDC  DNG       r--   Kodak Digital Camera Raw Image Format
    LABEL* LABEL     r--   Image label
      M2V  MPEG      rw+   MPEG Video Stream
      M4V  MPEG      rw+   Raw MPEG-4 Video
      MAC* MAC       r--   MAC Paint
   MAGICK* MAGICK    rw-   Predefined Magick Image (LOGO, ROSE, etc.); output same as 'H'
      MAP* MAP       rw-   Colormap intensities and indices
     MASK* MASK      rw+   Image Clip Mask
      MAT  MAT       rw+   MATLAB level 5 image format
    MATTE* MATTE     -w+   MATTE format
      MEF  DNG       r--   Mamiya Raw Image File
     MIFF* MIFF      rw+   Magick Image File Format
      MKV  MPEG      rw+   Multimedia Container
      MNG* PNG       rw+   Multiple-image Network Graphics (libpng 1.5.13)
           See http://www.libpng.org/pub/mng/ for details about the MNG
           format.
     MONO* MONO      rw-   Raw bi-level bitmap
      MOV  MPEG      rw+   MPEG Video Stream
      MP4  MPEG      rw+   MPEG-4 Video Stream
      MPC* MPC       rw+   Magick Persistent Cache image format
     MPEG  MPEG      rw+   MPEG Video Stream
      MPG  MPEG      rw+   MPEG Video Stream
      MRW  DNG       r--   Sony (Minolta) Raw Image File
      MSL* MSL       rw+   Magick Scripting Language
     MSVG  SVG       rw+   ImageMagick's own SVG internal renderer
      MTV* MTV       rw+   MTV Raytracing image format
      MVG* MVG       rw-   Magick Vector Graphics
      NEF  DNG       r--   Nikon Digital SLR Camera Raw Image File
      NRW  DNG       r--   Nikon Digital SLR Camera Raw Image File
     NULL* NULL      rw-   Constant image of uniform color
      ORF  DNG       r--   Olympus Digital Camera Raw Image File
      OTB* OTB       rw-   On-the-air bitmap
      OTF* TTF       r--   Open Type font (Freetype 2.4.11)
      PAL* UYVY      rw-   16bit/pixel interleaved YUV
     PALM* PALM      rw+   Palm pixmap
      PAM* PNM       rw+   Common 2-dimensional bitmap format
    PANGO* PANGO     r--   Pango Markup Language (Pangocairo 1.40.4)
  PATTERN* PATTERN   r--   Predefined pattern
      PBM* PNM       rw+   Portable bitmap format (black and white)
      PCD* PCD       rw-   Photo CD
     PCDS* PCD       rw-   Photo CD
      PCL  PCL       rw+   Printer Control Language
      PCT* PICT      rw-   Apple Macintosh QuickDraw/PICT
      PCX* PCX       rw-   ZSoft IBM PC Paintbrush
      PDB* PDB       rw+   Palm Database ImageViewer Format
      PDF  PDF       rw+   Portable Document Format
     PDFA  PDF       rw+   Portable Document Archive Format
      PEF  DNG       r--   Pentax Electronic File
      PES* PES       r--   Embrid Embroidery Format
      PFA* TTF       r--   Postscript Type 1 font (ASCII) (Freetype 2.4.11)
      PFB* TTF       r--   Postscript Type 1 font (binary) (Freetype 2.4.11)
      PFM* PFM       rw+   Portable float format
      PGM* PNM       rw+   Portable graymap format (gray scale)
      PGX* PGX       rw-   JPEG 2000 uncompressed format
    PICON* XPM       rw-   Personal Icon
     PICT* PICT      rw-   Apple Macintosh QuickDraw/PICT
      PIX* PIX       r--   Alias/Wavefront RLE image format
    PJPEG* JPEG      rw-   Joint Photographic Experts Group JFIF format (libjpeg-turbo 1.2.90)
   PLASMA* PLASMA    r--   Plasma fractal image
      PNG* PNG       rw-   Portable Network Graphics (libpng 1.5.13)
           See http://www.libpng.org/ for details about the PNG format.
    PNG00* PNG       rw-   PNG inheriting bit-depth, color-type from original if possible
    PNG24* PNG       rw-   opaque or binary transparent 24-bit RGB (zlib 1.2.7)
    PNG32* PNG       rw-   opaque or transparent 32-bit RGBA
    PNG48* PNG       rw-   opaque or binary transparent 48-bit RGB
    PNG64* PNG       rw-   opaque or transparent 64-bit RGBA
     PNG8* PNG       rw-   8-bit indexed with optional binary transparency
      PNM* PNM       rw+   Portable anymap
      PPM* PNM       rw+   Portable pixmap format (color)
  PREVIEW* PREVIEW   -w-   Show a preview an image enhancement, effect, or f/x
       PS  PS        rw+   PostScript
      PS2  PS2       -w+   Level II PostScript
      PS3  PS3       -w+   Level III PostScript
      PSB* PSD       rw+   Adobe Large Document Format
      PSD* PSD       rw+   Adobe Photoshop bitmap
     PTIF* TIFF      rw+   Pyramid encoded TIFF
      PWP* PWP       r--   Seattle Film Works
RADIAL-GRADIENT* GRADIENT  r--   Gradual radial passing from one shade to another
      RAF  DNG       r--   Fuji CCD-RAW Graphic File
      RAS* SUN       rw+   SUN Rasterfile
      RAW  DNG       r--   Raw
      RGB* RGB       rw+   Raw red, green, and blue samples
     RGBA* RGB       rw+   Raw red, green, blue, and alpha samples
     RGBO* RGB       rw+   Raw red, green, blue, and opacity samples
      RGF* RGF       rw-   LEGO Mindstorms EV3 Robot Graphic Format (black and white)
      RLA* RLA       r--   Alias/Wavefront image
      RLE* RLE       r--   Utah Run length encoded image
      RMF  DNG       r--   Raw Media Format
      RW2  DNG       r--   Panasonic Lumix Raw Image
      SCR* SCR       r--   ZX-Spectrum SCREEN$
      SCT* SCT       r--   Scitex HandShake
      SFW* SFW       r--   Seattle Film Works
      SGI* SGI       rw+   Irix RGB image
    SHTML* HTML      -w-   Hypertext Markup Language and a client-side image map
      SIX* SIXEL     rw-   DEC SIXEL Graphics Format
    SIXEL* SIXEL     rw-   DEC SIXEL Graphics Format
SPARSE-COLOR* TXT       -w+   Sparse Color
      SR2  DNG       r--   Sony Raw Format 2
      SRF  DNG       r--   Sony Raw Format
  STEGANO* STEGANO   r--   Steganographic image
      SUN* SUN       rw+   SUN Rasterfile
      SVG  SVG       rw+   Scalable Vector Graphics (RSVG 2.40.16)
     SVGZ  SVG       rw+   Compressed Scalable Vector Graphics (RSVG 2.40.16)
     TEXT* TXT       rw+   Text
      TGA* TGA       rw-   Truevision Targa image
THUMBNAIL* THUMBNAIL -w+   EXIF Profile Thumbnail
     TIFF* TIFF      rw+   Tagged Image File Format (LIBTIFF, Version 4.0.3)
   TIFF64* TIFF      rw-   Tagged Image File Format (64-bit) (LIBTIFF, Version 4.0.3)
     TILE* TILE      r--   Tile image with a texture
      TIM* TIM       r--   PSX TIM
      TTC* TTF       r--   TrueType font collection (Freetype 2.4.11)
      TTF* TTF       r--   TrueType font (Freetype 2.4.11)
      TXT* TXT       rw+   Text
     UBRL* BRAILLE   -w-   Unicode Text format
    UBRL6* BRAILLE   -w-   Unicode Text format 6dot
      UIL* UIL       -w-   X-Motif UIL table
     UYVY* UYVY      rw-   16bit/pixel interleaved YUV
      VDA* TGA       rw-   Truevision Targa image
    VICAR* VICAR     rw-   VICAR rasterfile format
      VID* VID       rw+   Visual Image Directory
     VIFF* VIFF      rw+   Khoros Visualization image
     VIPS* VIPS      rw+   VIPS image
      VST* TGA       rw-   Truevision Targa image
     WBMP* WBMP      rw-   Wireless Bitmap (level 0) image
     WEBP* WEBP      rw-   WebP Image Format (libwebp 0.3.0[0201])
      WMF* WMF       r--   Windows Meta File
      WMV  MPEG      rw+   Windows Media Video
      WMZ* WMF       r--   Compressed Windows Meta File
      WPG* WPG       r--   Word Perfect Graphics
        X* X         rw+   X Image
      X3F  DNG       r--   Sigma Camera RAW Picture File
      XBM* XBM       rw-   X Windows system bitmap (black and white)
       XC* XC        r--   Constant image uniform color
      XCF* XCF       r--   GIMP image
      XPM* XPM       rw-   X Windows system pixmap (color)
      XPS  XPS       r--   Microsoft XML Paper Specification
       XV* VIFF      rw+   Khoros Visualization image
      XWD* XWD       rw-   X Windows system window dump (color)
    YCbCr* YCbCr     rw+   Raw Y, Cb, and Cr samples
   YCbCrA* YCbCr     rw+   Raw Y, Cb, Cr, and alpha samples
      YUV* YUV       rw-   CCIR 601 4:1:1 or 4:2:2

* native blob support
r read support
w write support
+ support for multiple images

Code: Select all

$ convert -verbose svg:master.svg out.png
'inkscape' '/tmp/magick-6803_-33sIR9zMDa' --export-png='/tmp/magick-6803aU7CBPwD94pO' --export-dpi='96,96' --export-background='rgb(100%,100%,100%)' --export-background-opacity='1' > '/tmp/magick-6803cFRqpqPjWncs' 2>&1
svg:master.svg=>master.svg SVG 1841x1904 1841x1904+0+0 16-bit sRGB 5127B 0.170u 0:00.580
svg:master.svg=>out.png SVG 1841x1904 1841x1904+0+0 8-bit sRGB 527749B 0.370u 0:00.269
So it is trying to use inkscape for the plain SVG delegate action, and not the intentionally corrupted 'rxxxsvg-convert' one I set up! I thought inkscape was not on my system, because of:

Code: Select all

$ which inkscape
/usr/bin/which: no inkscape in (/home/premier/.nvm/versions/node/v9.11.1/bin:/home/premier/perl5/bin:/usr/local/cpanel/3rdparty/lib/path-bin:/usr/local/cpanel/3rdparty/lib/path-bin:/usr/local/cpanel/3rdparty/lib/path-bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/cpanel/composer/bin:/home/premier/bin)
$ rpm -qa | grep inkscape
$ locate inkscape
$
and strace shows some failures to find inkscape, then the job carries on regardless, perhaps using the built-in MSVG converter since I see no other interesting forks to external processes going on.

Code: Select all

[pid 14511] stat("/home/username/.nvm/versions/node/v9.11.1/bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/home/username/perl5/bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/local/cpanel/3rdparty/lib/path-bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/local/cpanel/3rdparty/lib/path-bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/local/cpanel/3rdparty/lib/path-bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/local/bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/local/sbin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/usr/sbin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/opt/cpanel/composer/bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[pid 14511] stat("/home/username/bin/inkscape", 0x7fff5ad2afe0) = -1 ENOENT (No such file or directory)
[cut...]
[pid 14512] write(2, "sh: inkscape: command not found\n", 32) = 32
And the 'blah:' delegate, which I thought was ignoring delegates.xml, is actually using it:

Code: Select all

$ convert -verbose blah:master.svg out.png
'/usr/local/bin/rsvg-convert' -o '/tmp/magick-7255j1eCUY5UwSi9' '/tmp/magick-72552Fyt2Yy8TFD2'
blah:master.svg=>master.svg PNG 1841x1904 1841x1904+0+0 8-bit sRGB 79590B 0.040u 0:00.040
blah:master.svg=>out.png PNG 1841x1904 1841x1904+0+0 8-bit sRGB 79873B 0.500u 0:00.310
If you're interested here's a version of my SVG with some of the extra artwork removed that still shows the behaviour, it's three <path> elements each with a pattern fill where the image file is in the same folder as the SVG:

Code: Select all

<?xml version="1.0"?><svg xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1841.37 1903.92"><title>Love1-600x600</title><path id="background" d="M-53.7-88.5H1787.67V1815.42H-53.7Z" transform="translate(53.7 88.5)" fill="#fff"/><path id="frame1" d="M130.78,125.46H818.62v701H130.78Z" transform="translate(53.7 88.5)" fill="#fff" stroke="#000" stroke-miterlimit="10" stroke-width="0.97" style="fill: url(#image0);"/><path id="frame2" d="M882.17,125.46H1570v701H882.17Z" transform="translate(53.7 88.5)" fill="#fff" stroke="#000" stroke-miterlimit="10" stroke-width="0.97" style="fill: url(&quot;#image1&quot;);"/><path id="frame3" d="M130.78,874.29H818.62v701H130.78Z" transform="translate(53.7 88.5)" fill="#fff" stroke="#000" stroke-miterlimit="10" stroke-width="0.97" style="fill: url(&quot;#image2&quot;);"/>><defs><pattern id="image2" x="0" y="0" width="1" height="1"><image xlink:href="frame3_cherries-cropped-thumb.jpg" x="0" y="0" width="687.8399658203125" height="701.0000610351562"/></pattern><pattern id="image0" x="0" y="0" width="1" height="1"><image xlink:href="frame1_cactus-cropped-thumb.jpg" x="0" y="0" width="687.8399658203125" height="701"/></pattern><pattern id="image1" x="0" y="0" width="1" height="1"><image xlink:href="frame2_cake-cropped-thumb.jpg" x="0" y="0" width="687.8300170898438" height="701"/></pattern></defs></svg>

snibgo
Posts: 12169
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by snibgo » 2018-12-21T21:51:53-07:00

When using IM to convert SVG files that contain relative links to patterns etc, you might consider temporarily changing MAGICK_TEMPORARY_PATH to the directory of the SVG file. See http://www.imagemagick.org/script/resources.php

Normally, MAGICK_TEMPORARY_PATH is not set, and IM will use /tmp on *nix or %TEMP% on Windows for temporary files. So just unset it when your convert is done.
snibgo's IM pages: im.snibgo.com

neekfenwick
Posts: 10
Joined: 2018-08-11T21:56:10-07:00
Authentication code: 1152

Re: Centos Imagick readImage for SVG seems to ignore delegates.xml

Post by neekfenwick » 2018-12-22T06:13:25-07:00

[EDIT: original post claimed this wasn't working, but I noticed I was being a massive tool and missing that of course my attempt to run 'convert' on the command line has nothing to do with the environment of a PHP script running Imagick ]

Very good call snigbo .. I actually do have that call before my Imagick invocations and it was setting the temp dir to my web root cache dir. So I've changed this to set it to the directory containing the SVG file:

Code: Select all

$svgWorkDir = 'path/inside/web/root';
$masterSVGFilename = $svgWorkDir . 'master.svg';
putenv('MAGICK_TEMPORARY_PATH=' . $svg_work_dir);
$im = new Imagick();
$im->readImage('rsvg:' . $masterSVGFilename);
$im->setImageFormat('jpg')
$im->writeImage($outFilename);
putenv('MAGICK_TEMPORARY_PATH'); // unset variable
This seems to work well!

So I think I've learned the following when trying to convert an SVG with both <image> elements and <pattern> with inner <image> elements:

- Trying to change the 'svg' delegate in delegates.xml and specifying the delegate as 'svg:master.svg' has no effect, my system still seems to try to invoke 'inkscape' (as seen in 'convert -verbose svg:master.svg out.png' output).. although strace then shows inkscape not being found and the conversion goes ahead anyway, presumably using the rsvg built-in delegate (seen in 'convert -version') which is version 2.40.16 (seen in 'convert -list format' output)

- Built-in rsvg version 2.40.x (in my ImageMagick6 packages from remi) is obsolete and the team recommend using 2.42.x which I could easily build from source and install in /usr/local. This converts the images well.

- Create a new entry in delegates.xml called anything other than 'svg' e.g.:

Code: Select all

<delegate decode="rsvg" command="&quot;/usr/local/bin/rsvg-convert&quot; -o &quot;%o&quot; &quot;%i&quot;"/>
- Set your MAGICK_TEMPORARY_PATH to the same folder the SVG and images are in so that when Imagick writes your SVG file to a temporary file it's in the same location as the images for when rsvg-convert is invoked on it. (this is a big assumption that the SVG file and the images are in the same directory :) )

- Load the SVG using your delegate name prefix e.g. 'rsvg:somefile.svg'.

- Side note: part of the reason for all this chaos is that <image> and <pattern><image></pattern> elements seem to work differently in their file resolution. For an SVG with both using absolute pathnames, only the plain <image> elements render for me, the <path>s using a pattern fill appear empty. If I strip the path names to be just the filename, i.e. relative to the current directory, and use the temp dir trick above, then both image and path elements fill correctly. So, my solution also includes some stripping of the SVG before loading it into $im to remove the path names from images.

I'll stick with this, my only worry now is delegates.xml being overwritten and losing my rsvg delegate definition.

Thanks everyone! :)

Post Reply