🌊

SVG, PDF ベクタデータを 32K or more 画像にしたいメモ

2023/01/17に公開

背景

ベクタデータ生成し 16K 以上の解像度の画像にバッチ処理でラスタライズしたい...
(Linux, Windows で動くやつで...)

poppler, cairo 系

poppler だと 16K あたりまでしか扱えない
https://poppler.freedesktop.org/
あと poppler はビルドめんどい(一応 prebuilt あるが).

実際のところは cairo の制限です(poppler も cairo 使っているはず).

https://cairosvg.org/

cairosvg でも 32K あたりで canvas 生成時にエラーになりました.

cairo では内部では 16.16 精度で計算しているため(pixman の制限っぽい?), 32768 が最大になります.

また, poppler だと指定解像度(-scale-to-x など)に必ずしもマッチした解像度の画像が生成されないときもあります(aspect ratio 計算で誤差が出ている?)

Skia?

Python の skia binding で 64K x 64K まで Canvas 生成確認できました!

https://github.com/kyamagu/skia-python

ただし PNG 保存だとエンコードに時間かかります
(fpng_py https://github.com/K0lb3/fpng_py など fpng バインディングだと, 解像度多いと fpng が対応できていないのかクラッシュする)

SVG, PDF 読み込み?

Skia では SVG, PDF の読み込みはサポートしていません. なにか方法を考える必要があります.
.NET だと svg バインディングがあるようであるが...

https://github.com/wieslawsoltes/Svg.Skia

React native skia とか pdfjs + cairo backend で JS レイヤーで PDF ラスタライズできたりするじゃろか?
(また, 通常ブラウザ動作(HTML5 描画)だと canvas は 8K くらいまで)
Flutter ならいけるかもだけど, Flutter セットアップめんどいじゃ

svg-native-viewer が C++ で Skia backend で使っているので, svg-native-viewer いけるかもしれません.

https://github.com/adobe/svg-native-viewer

blend2d

できたてほやほやですが, svg を blend2d で処理する svg2b2d がありました.

https://github.com/Wiladams/svg2b2d

ただ微調整はできなさそうです.

とりあえずは DotNet の Svg.Skia 使うのがよいかもしれません.

画面分割?

4K とかのタイルに分けて処理して最後繋ぐという手もあります.
ただ, poppler ではオフセットかけてラスタライズというのは無いっぽいようです...
python + cairosvg とかで頑張ればいけるかもはしれません.

また, タイル間でラスタライズのずれのアーティストがでるかもしれません.

TODO

  • python-skia で SVG, PDF 読み込みのいい方法を探す.

Discussion