【Inkscape 擴展開發】SVG導入 - 鏈接SVG(linked SVG)轉包含SVG(included SVG)

背景

在 Stack Overflow 上問了個問題然後嘗試自己解決,發現除了在鏈接SVG上右鍵選擇“嵌入圖像”選項之外,並沒有其他的解法。“嵌入圖像”其實也不能解決問題,只是將原圖轉爲 base64 格式,並不能實現子圖內容可編輯。所幸 Inkscape 支持使用 Python 作爲腳本開發擴展,最後還是轉向了用自定義擴展解決問題。同時也發現國內關於 Inkscape 擴展開發的內容實在是鳳毛麟角,故寫下一點使用心得,希望能夠拋磚引玉。入門相對來說還是容易的,即使教程不多,通過閱讀源碼,也能夠了解到一些用法,在兩天之內便能夠寫出一個簡單的實現上述功能的擴展。

代碼

伸手黨可以直接訪問我的倉庫
Inkscape 擴展開發教程資源示例:

原型

擴展原型來自 Inkscape 官方 Gitlab 倉庫的《My First Effect Extension》教程項目壓縮包直接下載鏈接。跟着教程就能初步定製自己的擴展界面了。

debug

一旦按照上述教程將項目文件夾放到 Inkscape 指定的擴展目錄並重啓 Inkscape 使之識別以後,每當我們修改了代碼,可以不必重啓 Inkscape,只需要重新運行自己的擴展,代碼的改變就能立馬顯現出來。
想查看自己擴展的運行信息,可以使用self.msg這個函數將自己想 debug 的信息輸出來,方便查錯。

XPath

在SVG文件中查找特定節點可以用self.document.xpath函數,第一個參數是 XPath 表達式字符串,第二個參數是inkex.NSS,這個參數在下文會介紹。

xlink:href

鏈接SVG使用xlink:href鏈接源圖片,雖然對於一個節點,獲取其屬性可以使用類似node.attrib['id']這樣的方法,但是xlink:href中冒號前面的xlink屬於“命名空間”,使用node.attrib['xlink:href']是獲取不到值的。其實xlink:href全寫是{http://www.w3.org/1999/xlink}href,使用該鍵才能獲取到其值。

inkex.NSS

inkexinkscape+extension的縮寫,是一個 Python 的 Inkscape 擴展包。字典inkex.NSS存儲了SVG的命名空間,即SVG代碼中下面這部分的字典化:

<svg
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">

爲了防止xlink這個命名空間以後發生變化,可以不硬編碼{http://www.w3.org/1999/xlink}href,而是用'{{{0}}}href'.format(inkex.NSS['xlink'])這樣的方法來獲取xlink:href的全寫。

tag

修改標籤名可以通過類似element.tag = 'xxx'這樣的寫法來修改,這裏將標籤名修改成了xxx。不過要注意的是,這裏同樣需要帶上svg的命名空間,即element.tag = '{{{0}}}g'.format(inkex.NSS['svg']),這裏將標籤名修改成了羣組,即svg:g

通過插件導入 SVG

這裏可以看到inkex.elements下有個load_svg函數,可以將 SVG 地址鏈接(可通過node.attrib['{{{0}}}href'.format(inkex.NSS['xlink'])]獲取)通過lxml包轉爲 XML 節點對象,方便我們查詢與引用、插入。在父元素下插入新的節點使用的是father.append(child)這樣的方式。

Image 對象轉 Group 對象的注意事項

需要注意的是,將 image 標籤轉爲 g 標籤以後,xywidthheight這些屬性對 g 標籤是無法生效的,需要轉換爲transform屬性,即設置該屬性值爲translate(x,y) scale(width/oWidth, height/oHeight)xywidthheight從原 image 標籤獲取,oWidthoHeight從 image 標籤所引用的 SVG 圖像的svg:svg節點中獲取。注意一開始獲取到的值是字符串類型,需要轉換爲 float 類型才能進行運算;還要注意度量單位,這裏我偷懶,默認我獲取到的值的單位都是px,不排除有些是mmcm,自己注意寫代碼檢測與轉換。如此設置以後,便能得到與 image 標籤一樣的圖像大小、位置效果,實現從 linked SVG 到 included SVG 的無縫轉換。

便捷模塊

Inkscape 除了 inkex 模塊以外,還有一些便捷模塊方便你的開發,如simpletransform,可以將上述的 transform 由文本設置改爲用函數設置(詳情)。但由於官方 Wiki 的這則公告,我不打算使用這些便捷模塊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章