I have SVG images produced by PlantUML, which has some parts of drawing outside of canvas. It makes it difficult to use such images and I need to crop drawing to canvas size. As I produce UML diagrams with script anyways, it would be really efficient to perform a cropping there as well.

So far I've tried two things: a) resize canvas to drawing with Inkscape

inkscape --verb=FitCanvasToDrawing --verb=FileSave --verb=FileClose *.svg

This works fine, but I need to crop drawing to canvas size and this operation seems to be unavailable.

b) resize with rsvg-convert

rsvg-convert image.svg -w 1870 -h 1195 -f svg -o image.svg

This does exactly croping to the desired size, but image size increases ~10 times as now there are some binary images embedded into SVG. This is not acceptable for me.

  • Not an answer, just a suggestion (I'm not looking up the specs right now). svg format is a xml-based ascii format, so the easiest way should be just to use sed or your favourite text manipulation tool to insert or modify a line that sets the bounding box. This wouldn't even touch the other contents of the file. Try doing it manually once on an example svg file (in a text editor) and then translate your actions into a script. – orion May 7 '14 at 13:19
  • Canvas size is fine. I have to crop all texts, lines and rectangles, which have parts outside of a canvas. That requires comparing their bounding boxes and with canvas box. This is way to much for just a shell script. – divanov May 7 '14 at 13:26
  • 1
    Oh... I remember I was angry over inkscape why it doesn't do that. There was even a bug report involved. They didn't do anything about it at that time. Also, there are no standard tools to remove invisible out-of-bounds stuff from pdf files (Acrobat Pro of course is one of the worst here). However, if you just want to clip partially visible stuff, you could group the entire contents and put a bounding-box-sized clip over everything. They are still in the file though, and they still take up space. – orion May 7 '14 at 13:32
  • Thank you for the suggestion. Altering xml with sed is slightly dangerous, but still better than manual editing. – divanov May 8 '14 at 6:00

I found an inelegant way to do that using orion's proposal. Assuming $svg_file_name is a variable containing file path to an SVG image.

First we need image width and height

width=$(exiftool -ImageWidth $svg_file_name | sed "s/.*: //;s/pt//g")
height=$(exiftool -ImageHeight $svg_file_name | sed "s/.*: //;s/pt//g")

PlantUML produces the diagram as a single group (tag <g>), let's place rectangle of canvas size over that group

sed -i "s|</g>|</g><polygon fill=\"#FFFFFF\" points=\"0,0,0,$height,$width,$height,$width,0\" style=\"stroke: #000000; stroke-width: 1.0;\"/>|" $svg_file_name

Now open image with inkscape, select all and clip the group with the rectangle

inkscape --verb=EditSelectAll --verb=ObjectSetClipPath --verb=FileSave --verb=FileClose $svg_file_name

With the latest Inkscape one needs to quit Inkscape instead of closing the file

inkscape --verb=EditSelectAll --verb=ObjectSetClipPath --verb=FileSave --verb=FileQuit $svg_file_name
  • Note that some svgs might use "mm" units and a viewBox. Then the height and width need to be adjusted according to the scaling. More info here. – jmiserez Aug 25 '16 at 13:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.