Beschneiden Sie die SVG-Zeichnung in der Befehlszeile auf Leinwandgröße

9

Ich habe SVG-Bilder von PlantUML, die einige Teile der Zeichnung außerhalb der Leinwand haben. Es macht es schwierig, solche Bilder zu verwenden, und ich muss die Zeichnung auf Leinwandgröße zuschneiden. Da ich sowieso UML-Diagramme mit Skript erstelle, wäre es sehr effizient, dort auch ein Zuschneiden durchzuführen.

Bisher habe ich zwei Dinge ausprobiert: a) Ändern Sie die Größe der Leinwand, um mit Inkscape zu zeichnen

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

Dies funktioniert gut, aber ich muss die Zeichnung auf Leinwandgröße zuschneiden, und dieser Vorgang scheint nicht verfügbar zu sein.

b) Ändern Sie die Größe mit rsvg-convert

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

Dadurch wird genau auf die gewünschte Größe zugeschnitten, aber die Bildgröße erhöht sich um das Zehnfache, da jetzt einige Binärbilder in SVG eingebettet sind. Das ist für mich nicht akzeptabel.

Divanov
quelle
Keine Antwort, nur ein Vorschlag (ich schaue gerade nicht nach den Spezifikationen). svgDas Format ist ein XML-basiertes ASCII-Format. Der einfachste Weg ist daher, sedeine Zeile, die den Begrenzungsrahmen festlegt , mit Ihrem bevorzugten Textbearbeitungswerkzeug einzufügen oder zu ändern. Dies würde nicht einmal den anderen Inhalt der Datei berühren. Versuchen Sie es einmal manuell in einer Beispiel-SVG-Datei (in einem Texteditor) und übersetzen Sie dann Ihre Aktionen in ein Skript.
Orion
Leinwandgröße ist in Ordnung. Ich muss alle Texte, Linien und Rechtecke zuschneiden, die Teile außerhalb einer Leinwand haben. Dazu müssen die Begrenzungsrahmen mit dem Leinwandrahmen verglichen werden. Dies ist viel zu viel für nur ein Shell-Skript.
Divanov
1
Oh ... ich erinnere mich, dass ich über Tintenlandschaft wütend war, warum es das nicht tut. Es gab sogar einen Fehlerbericht. Sie haben damals nichts dagegen unternommen. Außerdem gibt es keine Standardtools zum Entfernen von unsichtbarem Out-of-Bound-Material aus PDF-Dateien (Acrobat Pro ist hier natürlich eines der schlechtesten). Wenn Sie jedoch nur teilweise sichtbare Inhalte ausschneiden möchten, können Sie den gesamten Inhalt gruppieren und einen Clip in Bounding-Box-Größe über alles legen. Sie befinden sich jedoch immer noch in der Datei und belegen immer noch Speicherplatz.
Orion
Vielen Dank für den Vorschlag. Das Ändern von XML mit sed ist etwas gefährlich, aber immer noch besser als das manuelle Bearbeiten.
Divanov

Antworten:

5

Ich habe einen uneleganten Weg gefunden, dies mit dem Vorschlag von orion zu tun. Angenommen, es $svg_file_namehandelt sich um eine Variable, die den Dateipfad zu einem SVG-Bild enthält.

Zuerst brauchen wir Bildbreite und -höhe

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

PlantUML erstellt das Diagramm als einzelne Gruppe (Tag <g>). Platzieren Sie ein Rechteck mit Leinwandgröße über dieser Gruppe

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

Öffnen Sie nun das Bild mit inkscape, wählen Sie alle aus und schneiden Sie die Gruppe mit dem Rechteck ab

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

Mit dem neuesten Inkscape muss Inkscape beendet werden, anstatt die Datei zu schließen

inkscape --verb=EditSelectAll --verb=ObjectSetClipPath --verb=FileSave --verb=FileQuit $svg_file_name
Divanov
quelle
Beachten Sie, dass einige SVGs möglicherweise "mm" -Einheiten und eine ViewBox verwenden. Dann müssen Höhe und Breite entsprechend der Skalierung angepasst werden. Mehr Infos hier .
Jmiserez