Kann ich SVG-Text in Pfade konvertieren, aber Glyphen wiederverwenden?

Ich habe eine SVG mit einer Menge Text darauf. Es ist ein Parkplatzplan mit Platznummern darauf geschrieben. Ich zeige dies in einem Webbrowser an und dank eines wunderbaren kleinen Fehlers in Firefox gibt der Browser den Text falsch wieder. Buh.

Also habe ich den Text in Pfade umgewandelt. Wir sprechen von bis zu 4000 separaten Labels. Vielleicht 15.000 neue Formen, jetzt sind sie Vektoren. Es sind 4 MB. Normalerweise könnten Sie argumentieren, dass sich dies für eine Komprimierung eignen würde, aber ich muss dieses SVG in das HTML einfügen . Ich füge CSS-Änderungen dynamisch hinzu, und nur so habe ich eine Chance auf browserübergreifende Unterstützung. Jedenfalls ist die rohe – sogar bereinigte – Ausgabe davon zu groß, um nützlich zu sein.

Was mir hier auffällt, ist, dass all diese Leerzeichen gemeinsame Glyphen haben. Null bis neun. Warum füge ich für jede Instanz jeder Zahl eine Formdefinition hinzu? Kann ich diese deduplizieren?

Ich verwende Inkscape, bin aber offen für Vorschläge.

Besteht die Möglichkeit, dass Sie die SVG-Datei teilen, damit wir damit experimentieren können?
Was genau ist der Fehler (Screenshot) und wie exportieren und laden Sie ihn in einen Browser? Es besteht eine gute Chance, dass Sie es mit nur etwas CSS-Stil oder einem kleinen Skript auf der Seite beheben können, um die Textelemente zu reparieren/ersetzen. Wenn es sich um eine dynamische Kartenanzeige handelt, möchten Sie sie vielleicht in eine tatsächliche Karte umwandeln – die meisten Browser-Mapping-Bibliotheken (und viele datenbasierte) bieten eine hervorragende Unterstützung für Beschriftungen.
Tut mir leid, das SVG darf ich nicht teilen (es gehört einem Kunden), aber der Fehler ist bekannt über . Es bedeutet im Wesentlichen, dass die Schriftarten in der SVG nicht über einen Punkt hinaus verkleinert werden ... Was ein ernstes Problem ist, wenn Sie auf einer Karte mit Tausenden von nummerierten Parkplätzen ganz herausgezoomt haben. Sie sollten (z. B.) ~ 0,08 pt sein und sind tatsächlich 13 pt.
Sie haben die falsche Fehlernummer, Sie suchen eigentlich nach dieser
Vielleicht möchten Sie dies an einer Teilmenge testen, aber kann path|simplifyIhnen das überhaupt helfen? Ein kleines „s“ wird in einen 28-Punkte-Pfad konvertiert, vereinfacht es auf 17, und das Überlagern der vereinfachten und nicht vereinfachten Versionen wird sogar gezoomt, sodass ein „s“ den Bildschirm ausfüllt, es gibt keinen Unterschied.
Außerdem suche ich nach einem Skript, das ich vor einigen Jahren geschrieben habe, um Entitäten in einer SVG-Datei zu deduplizieren (ziemlich dumme Ausgabe eines 3D-Modells). Ich glaube, das hatte auch eine Option zum Abschneiden der Genauigkeit, mit der ein paar Bytes pro Koordinate eingespart werden konnten
Gefunden, und nein, es hat keine Präzisionsreduzierung.
Ich habe eine weitere Ausgrabung und stelle fest, dass jedes Textelement, wenn es in einen Pfad konvertiert wird, seine Schriftartinformationen behält. Das sind in meinem Test 320 B pro Element, was für Sie etwas mehr als 1 MB bedeuten würde. Sie können die SVG-Datei in einem Texteditor auf Gruppen untersuchen, die ein text-styleund ein idpassendes Textelement haben, das Sie zuvor hatten, aber keinen tatsächlichen Text, um festzustellen, ob diese von den von Ihnen verwendeten Tools optimiert wurden (dh ob die Tools die Gruppen leer)

Antworten (4)

Mit dem <use>Element können Sie an anderer Stelle im Dokument definierte Objekte wiederverwenden. Beispielsweise könnten Sie jede Glyphe als definieren <symbol>und sie dann mehrmals wiederverwenden. Hier ist ein netter Artikel darüber: Structuring, Grouping, and Referencing in SVG — The <g>, <use>, <defs>und <symbol>Elements .

Ich weiß jedoch nicht, wie ich das direkt in Inkscape machen soll - besonders nicht für eine Menge Text, den Sie bereits als Text haben. Möglicherweise müssen Sie ein Skript schreiben, um das SVG nachzubearbeiten und alle Pfade zu finden, die wiederverwendet werden können.

Das <use>war, was ich dachte, als ich das fragte, das Scripting ist das Wie. Scheint albern, dass es nichts gibt, um nahezu identisches Markup zu deduplizieren.
@Oli es gab nichts, um identisches Markup zu deduplizieren ; Ich musste meine eigenen schreiben (und mit identisch meine ich das Byte; ich habe sie gehasht und Hashes verglichen)
Ich habe beim Mittagessen nachgedacht, und es fühlt sich für mich so an, als wäre ein (Python-)Skript in Inkscape der richtige Weg. Das Skript würde mit dem Text als Text beginnen und ihn durch Verweise auf das <symbol>s ersetzen (oder es sieht so aus, als könnten Sie <def>Ihre Text-zu-Pfad-Glyphen

Es stehen einige Komprimierungsoptionen zur Verfügung, die unterschiedlich erfolgreich sind. Um sie zu testen, habe ich eine Grafikdatei erstellt, die nur viel wiederholten Text enthielt. Unerweitert beträgt die Dateigröße 13,8 KB. Erweitert beträgt die Dateigröße 1,42 MB .

Gute Option: Verwenden Sie SVGZ - 46,5 KB

Das Speichern des erweiterten Bildmaterials als SVGZ ergab eine Ausgabedatei von 46,5 KB, die deutlich kleiner als die Standard-SVG ist. Beachten Sie jedoch, dass die Unterstützung variieren kann .

Bessere Option: Mit Scour komprimieren - 21,1 KB

Scour ist ein Tool, das Ihre SVG-Datei für Sie säubert und optimiert. Mit dem Befehl "maximale Komprimierung" von scour -i input.svg -o output.svgz --enable-viewboxing --enable-id-stripping --enable-comment-stripping --shorten-ids --indent=nonewurde das erweiterte Bildmaterial auf 21,1 KB reduziert. Nicht weit entfernt von der ursprünglichen nicht erweiterten Dateigröße!

Beim Scouring wird nicht komprimiert, es entfernt nur Müll, und obwohl es mir ziemlich gut tut (angesichts der großen Anzahl von Objekten), waren meine "4 MB" nach dem Scouring. Komprimierter Inhalt wäre großartig, aber – und ich hätte das früher erwähnen sollen – ich muss das SVG für Browser-Targeting-Probleme (und auch für Anforderungen zur Frontend-Manipulation) inlinen. Ich weiß, ich weiß, es tut weh, aber vertrau mir, wenn ich sage, dass es mir im Moment mehr wehtut D:
Ich hätte sagen sollen, dass der Scheuerteil scournicht komprimiert. Es kann die Datei auch für Sie durch gzip werfen, aber das ID- und Whitespace-Minification-Zeug ist seine Hauptaufgabe.
@Oli richtig, daher meine sorgfältige Wahl des Wortes "optimieren" :) Das ist ein Mist, dass Ihre Datei bereits durchforstet ist ... ack!
Ich habe ein bisschen in Illustrator herumgespielt; seine SVG-Ausgabe respektiert Symbols . Hier ist ein kurzes Beispiel . Es würde ziemlich viel Aufwand erfordern, aber Sie können möglicherweise ein Illustrator-Skript erstellen, das Ihren Text in einzelne Zeichen zerlegt und diese durch Symbole ersetzt. Die größte Hürde sehe ich im Umgang mit der Rotation. Wenn der gesamte Text parallel zur X-Achse ist, scheint es nicht schwierig zu sein, aber der Umgang mit Text in einem Winkel kann eine Herausforderung sein. All das ist natürlich nicht sehr hilfreich, wenn Sie Illustrator nicht zur Verfügung haben

Dies ist eine In-Browser- oder Server-Lösung

Es gibt viele verschiedene Möglichkeiten, SVG-Dateien zu optimieren. Klingt, als hättest du schon einiges geschafft.

Ein paar Quellen, die ich sehr nützlich fand, sind ein CSS-Tricks-Artikel , der sich auf sehr spezifische Details konzentriert. Und insbesondere das verwendete Tool SVGO .

Wenn Sie viele, sich wiederholende Pfade haben, würde ich in Betracht ziehen, Javascript zu verwenden, um die Formen dynamisch zu erstellen. Hier ist ein Beispiel . Eine Richtung wäre, eine definierte Funktion für jede Glyphe zu haben und einfach jeden Pfad innerhalb des svg-Elements durch eine Anfrage für diese Funktion zu erstellen. Oder nehmen Sie einen vollständigen String und/oder ein Array von Argumenten, um Ihr Inline-Svg zu erstellen. Dies setzt natürlich voraus, dass Ihre Pfade länger sind als die Länge des Codes, der zum Anfordern dieser Funktion erforderlich ist (ziemlich einfache Annahme).

Während diese Antwort mehrere mögliche Lösungen bietet, scheint SVGO am interessantesten zu sein. Es könnte auch auf einer .svg-Datei ausgeführt werden, um es zu optimieren. Es scheint jedoch derzeit keine Pfaddeduplizierung durchzuführen. Wenn der Fragesteller trotzdem benutzerdefinierte Skripte erstellt, könnte es eine gute Idee sein, dies als Erweiterung von SVGO zu tun.
@jpa Deduplizierung vor (oder während) der Konvertierung in Pfade wäre sicherlich der richtige Weg. Ersetzen Sie alle Instanzen des Textzeichens „1“ durch <use xlink:href="#digit_one">wo digit_oneein Pfad ist
@ChrisH Ich kann nicht verstehen, warum man danach nicht genauso gut deduzieren konnte. Normalisieren Sie einfach alle Pfade zum Ursprung am Startpunkt, nehmen Sie den Hash und verwenden Sie diesen, um festzustellen, ob der Pfad bereits aufgetreten ist. Sicher, nicht so elegant, aber sollte funktionieren und könnte einfacher zu implementieren sein, als die gesamte Textlayoutlogik neu implementieren / herausfinden zu müssen.
@jpa könntest du, aber wenn durch die Normalisierung des Ursprungs Rundungsfehler eingeführt würden, würde der Hash nicht übereinstimmen. Das Skript, an das ich denke, würde Inkscapes Text-zu-Pfad aufrufen, um die Zeichenpfade anzulegen, sie dann aber durch Verweise auf eine Reihe von Mastern ersetzen.
@jpa und die Rundungsfehler sind real. Bei einem Spielzeugbeispiel unterscheidet sich die erste quadratische Kurve einer Null um 1 an der sechsten Dezimalstelle – genug, um das Hashing zu vermasseln

Hier ist auf sehr hohem Niveau, was Ihr Skript tun sollte. Fühlen Sie sich frei, Ihre bevorzugte Sprache und Umgebung zu verwenden, dies ist nur ein Ausgangspunkt für eine Logik, die Ihnen geben sollte, wonach Sie suchen.

  • Durchlaufen Sie alle Textelemente in der XML-Datei des SVG und ändern Sie für diejenigen, die numerischen Text enthalten (die Parkplätze, Sie geben nicht an, ob mehr Text in Ihrem SVG vorhanden ist), die von Inkscape automatisch erstellte ID in eine Zeichenfolge mit diesem Parkplatz die Nummer des Spots. Inkscape benötigt nur eindeutige IDs, es generiert nicht beschreibende IDs, respektiert und ändert jedoch keine IDs, die von anderer Software erstellt oder vom Benutzer manuell erstellt oder geändert wurden.
  • Speichern Sie in einer Tabelle die x- und y-Koordinaten des Textelements jedes Parkplatzes.
  • Ob in Inkscape oder per Skript, wandeln Sie alle Parkplatztexte in Pfade um.
  • Hängen Sie für die Ziffern 0-9 einen entsprechenden <defs>Abschnitt an die SVG-Datei an, der die Pfadinformationen für jede Ziffer definiert.
  • Durchlaufen Sie alle <g>s der Parkplätze und ersetzen Sie sie durch a<use xlink:href="#digit" x=x y=y />
  • Profitieren

Ich kann einige Komplikationen vorhersehen, mit denen Sie fertig werden müssen, und viel Glück dabei.

  • Die Schleife muss die Reihe von Parkplätzen mit 2 oder mehr Ziffern aufteilen, und der angemessene Abstand zwischen der ersten Ziffer und den nachfolgenden Ziffern kann schwierig sein. Dies hängt stark von den Schriftarten ab, die Sie verwenden.
  • Sie geben nicht an, in welcher Ausrichtung sich die Parkplätze befinden oder ob sie überhaupt auf gekrümmten Setups liegen. Aufgrund der manuellen XY-Offsets für zweistellige Zahlen und mehr benötigen Sie möglicherweise zusätzliche Logik, um die „Ausrichtung“ eines Parkplatzes herauszufinden und die unterschiedlichen Pfade einzelner Ziffern von der ersten richtig zu platzieren.

Hoffe das hilft. Viel Glück.