SVGをお手軽に出力するならQtが最強のライブラリではないか?


PythonでSVGファイルを出力する方法を調べていたが、python最強のSVGライブラリsvgwriteよりも、Qt(PySide)の方がお手軽さでは最強なのではないかという結論に達した(異論は認めます)。

SVGとは?

SVGを知らないという方はまずいないと思うが、一応説明しておく。

SVGとはベクター画像形式の代表的な形式の1つである。従来のラスター形式の画像と比べ拡大縮小してもジャギが出ないため、ウェブブラウザ等の環境により表示サイズが変動する場所でも美しい表示ができる。

Qtを使ったSVGの出力

Qt(PySide)を使用したSVGの出力は、QSvgGeneratorを使う。
PySideでSVGを出力する簡単なサンプルを見てみよう。

#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtSvg import *

app = QApplication(sys.argv)

svg_gen = QSvgGenerator()
svg_gen.setFileName("hello.svg")
svg_gen.setSize(QSize(200, 80))
svg_gen.setViewBox(QRect(0, 0, 200, 80))
svg_gen.setTitle("hello svg")
svg_gen.setDescription("this is sample svg.")

painter = QPainter()
painter.begin(svg_gen)

rect = QRect(0, 0, 200, 80)
painter.fillRect(rect, Qt.yellow)

painter.setPen(Qt.blue)
painter.setFont(QFont("Arial", 30))
painter.drawText(rect, Qt.AlignCenter, "Hello SVG")

painter.end()

表示結果(※SVGが貼り付けられないためPNGで表示)

注意点はfrom PySide.QtSvg import *でSVG関連のモジュールをインポートしている事のみ。

QSvgGeneratorにSVGの設定を入力するだけで、後はQPainterを使って従来通りの描画をするだけである。
SVGのエレメント操作などは一切していないが、これだけでSVGファイルが作成されるのだ。
(もちろん完全なSVGの変換ではない、テキストのwrapなどSVGにそもそもない機能は無視される)

ちなみにSVGの描画はQSvgWidget、またはQGraphicsSvgItemでQGraphicsViewで表示もできる。

QGraphicsSceneからのSVG出力(2017-01-05 追記)

QGraphicsSceneからもSVG出力が可能である。

scene = QGraphicsScene()

rect = QRect(0, 0, 200, 80)

scene.setSceneRect(rect)
scene.addRect(rect, QPen(Qt.transparent), QBrush(Qt.yellow))
text_item = scene.addText("Hello SVG", QFont("Arial", 30))
text_item.setDefaultTextColor(Qt.blue)

painter = QPainter()
painter.begin(svg_gen)

scene.render(painter)

painter.end()

QGraphicsSceneを出力できるのは大きい、QGraphicsViewでマウスなどでアイテム位置を調整し、そのままSVGに出力できるのである。
お手軽にSVGのライブプレビュー環境が出来上がるのだ。

svgwriteへの優位性

svgwriteは柔軟性があり、非常に使いやすいライブラリである。
しかし、Qtを使った場合と比較してsvgwriteに対しての優位性を挙げていきたい。

svgwriteはgetBBoxが存在しない

svgwriteは良くも悪くもXMLのラッパー的な存在であるため、表示時のバウンティボックスを求めるgetBBoxが存在しない。
これはテキストを扱う場合、テキストの大きさがわからないため非常に困る。

SVGエレメントの知識が不要

SVGを出力するのだから、エレメントに対する知識が必要なのは当然であるのだが、Qtを使えばエレメントに対する知識が一切なくてもSVGを出力できる。

作成過程のプレビューが容易

プログラム上でSVGを出力する場合、トライ&エラーが必要である。
Qtを使えばQPainterの描画がそのままSVGになるため、必然的にプレビュー環境が出来上がっているのである。
SVGに変換後もQSvgWidgetで確認ができるため、プログラムさえ組んでしまえばライブプレビューで修正と作成が同時に行える。

SVGのバージョンについて

Qt5が扱えるSVGのバージョン1.2である、しかしPySideを使った場合Qt4.8であるのでSVGのバージョンは1.1なので注意。
PySide2が一刻も早く正式リリースされるの祈るばかりである。

まとめ

Qtを使ったSVGの出力は非常にお手軽である。
Qtを知っていればSVGの知識がほぼなくても良いのは、SVG初心者にとっては大きなアドバンテージである。

HTML5との連携やスタイルシートの適用など、柔軟性のあるSVGの作成はsvgwriteに譲らざるをえないが、表示のみのSVGであればQtは大きな選択肢となる。

SVGの自動生成の使いどころ

ちなみに、私はC言語の構造体を自動解析してブロック図(という名称なのだろうか?)をSVGで出力している。
BITMAPINFOHEADER構造体は以下のような図が出力される。

Sphinxなどのマニュアルに、自動生成で埋め込めばパティングなどの構造が分かるため便利である。