Inkscape - export vektorových ikon

04.04.2021 | 13:30 | Mirecove dristy | Miroslav Bendík

V dnešnom článku si porozprávame o tom, ako z webového dizajnu v svg exportovať vektorové ikony pomocou inkscape.

Ako na to?

Export časti svg zo svg je triviálna záležitosť. Inkscape je predsa svg editor, takže to musí ísť jednoducho. Poďme teda na to 😉

Začneme otvorením obrázka. Označíme časť, ktorú chceme exportovať a pozrieme si veľkosť vybranej časti v toolbare.

Veľkosť výberu
Obrázok 1: Veľkosť výberu

Teraz vytvoríme nový dokument (napr. klávesovou skratkou Ctrl+N. Po vytvorení nového dokumentu musíme nastaviť veľkosť domumentu. Vlezieme teda do menu Súbor / Vlastnosti dokumentu. V nastaveniach dokumentu musíme upraviť zobrazované jednotky z mm na px. Ďalej v sekcii vlastná veľkosť nastavíme veľkosť výberu (v tomto prípade 16 a 12 px). Ďalej musíme upraviť mierku dokumentu na 1 a tak isto musíme upraviť výšku a šírku dokumentu v časti Viewbox.

Vlastnosti dokumentu
Obrázok 2: Vlastnosti dokumentu

Teraz môžme smelo skopírovať časť dokumentu do nového dokumentu. V toolbare z obrázku 1 následne nastavíme pozíciu objektu na súradnice 0, 0.

Uloženie súboru
Obrázok 3: Uloženie súboru

Zostáva už len uložiť súbor, takže otvoríme Súbor / Uložiť ako, vyberieme formát optimalizované svg, pretože defaultný formát je extrémne blbosťami preplácaný, vyklikáme optimalizácie, potvrdíme uloženie, teraz stačí už len zatvoriť okno exportu, zatvoriť okno obrázka, potvrdiť zatvorenie okna a je to. No dobre, to by šlo, ale, musí to ísť aj jednoduchšie.

Jednoduchšie?

Inkscape porporuje export časti obrázka. Samozrejme ako správny vektorový editor dokáže obrázky exportovať len v rastrovom formáte 🤔

Hľadanie ma v prvom rade zaviedlo k tomuto bugu z roku 2005, alebo k trochu novšiemu bugu.

No dobre, takže export vo vektorových formátoch nemáme. Čo tak vytvoriť nový dokument priamo z výberu? Ani to nie.

Poďme to opraviť

It's 🔨🕒

Inkscape umožňuje vyvíjať vlastné rozšírenia. Tak si poďme rozšíriť inkscape o export výberu do samostatného súboru.

Začneme popisom pluginu. Popis uložíme do adresára s rozšíreniami (nájdeme ho v nastaveniach - Úpravy / Nastavenia / Systém / Používateľské rozšírenia pod názvom export_selection.inx). Popis tohto súboru nájdeme na tejto adrese. Okrem popisu som tam pridal aj parameter pre nastavenie cesty pre export a nastavenie transformácie. Výsledný súbor vyzerá takto:

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
    <_name>Export selection as svg</_name>
    <id>sk.linuxos.export_selection</id>

    <dependency type="executable" location="extensions">export_selection.py</dependency>
    <dependency type="executable" location="extensions">inkex.py</dependency>

    <param name="wrap_transform" type="boolean" _gui-text="Wrap final document in transform">false</param>
    <param name="export_dir" type="string" gui-text="Path to save image">./inkscape_export/</param>

    <effect needs-document="true" needs-live-preview="false">
        <object-type>all</object-type>
        <menu-tip>Export selection to separate SVG file.</menu-tip>
        <effects-menu>
            <submenu _name="Export"/>
        </effects-menu>
    </effect>

    <script>
        <command reldir="extensions" interpreter="python">export_selection.py</command>
    </script>
</inkscape-extension>

Ďalej pokračujeme súborom export_selection.py. V nasledujúcom výpise je základná kostra pluginu. Pri vyvolaní cez menu Export / Export selection as svg len vypíše argumenty skriptu.

# -*- coding: utf-8 -*-
import inkex
import sys


class ExportObject(inkex.EffectExtension):
    def add_arguments(self, pars):
        pars.add_argument(
            "--wrap_transform",
            action="store",
            type=inkex.Boolean,
            dest="wrap_transform",
            default=False,
            help="Wrap final document in transform"
        )
        pars.add_argument(
            "--export_dir",
            default="~/inkscape_export/",
            help="Location to save exported documents."
        )

    def effect(self):
        sys.stderr.write(str(self.options))


if __name__ == '__main__':
    action = ExportObject()
    action.run()

Skript taktiež môžme spustiť z terminálu príkazom inkscape --actions="select-by-id:[ID objektu]; verb:sk.linuxos.export_selection.noprefs" --batch-process vstup.svg.

Vo funkcii add_arguments sa definujú agrumenty. Tie sa musia zhodovať s argumentmi definovanými v inx súbore. Samotné vykonanie akcie bude implementované v metóde effect.

Teraz môže začať skutočná sranda. API rozšírení nájdeme na tejto adrese, ale omnoho užitočnejšie nám bude pri vývoji rovno pozerať do kódu modulu inkex, alebo do kódu existujúcich rozšírení.

Našťastie, alebo žiaľ, ako pre koho máme minimálne možnosti pri volaní interných funkcií inkscapu. Dokonca aj tie akcie, ktoré sa dajú volať fungujú tak, že spustia novú inštanciu inkscape a vykonajú batch process (ešte aj s otvorením a zatvorením ďalšieho okna). Takto napríklad vyzerá príkaz pre zrušenie zoskupenia objektu s vybraným ID:

inkex.command.inkscape_command(document, select=GROUP_ID, verbs=['SelectionUnGroup'])

Zoznam príkazov inkscapu sa dá získať príkazom inkscape --verb-list.

Druhý spôsob, ktorým sa dá upravovať dokument je priama modifikácia objektu self.svg, čo je v podstate len wrapper nad lxml.etree. Môžme teda dokument smelo modifikovať pomocou lxml volaní.

Výsledný skript, ktorý exportuje výber v optimalizovanom formáte pomocou optimalizátora scour som zverejnil na githube. Použitá je ako priama modifikácia DOM, tak aj volanie batch príkazov inkscape, pretože som nenašiel jednoduchý spôsob, ako objekty vyňať zo skupiny.

Plugin sa dá spomenutým príkazom spustiť priamo z konzoly bez interackie užívateľa, alebo, čo sa mi zdalo najpohodlnejšie skript sa dá nabindovať na klávesovú skratku cez Upraviť / Nastavenia / Rozhranie / Klávesové skratky a export následne prebieha spôsobom: vyberiem objekt, stlačím klávesovú skratku, hotovo. Výsledkom je optimalizované svg vhodné priamo na použitie vo webovej stránke (napr. vo forme SVG spritov).

Ukážka výsledného svg (kompletný obrázok):

<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <path d="m8 8a2.319 2.319 0 0 1-1-0.336l-7-3.664v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7l-7 3.664a2.319 2.319 0 0 1-1 0.336zm7-8h-14a1 1 0 0 0-1 1v0.758l8 4.2 8-4.2v-0.758a1 1 0 0 0-1-1z" fill="#777"/>
</svg>