SVG, PDF ベクタデータを 32K or more 画像にしたいメモ
背景
ベクタデータ生成し 16K 以上の解像度の画像にバッチ処理でラスタライズしたい...
(Linux, Windows で動くやつで...)
poppler, cairo 系
poppler だと 16K あたりまでしか扱えない
あと poppler はビルドめんどい(一応 prebuilt あるが).実際のところは cairo の制限です(poppler も cairo 使っているはず).
cairosvg でも 32K あたりで canvas 生成時にエラーになりました.
cairo では内部では 16.16 精度で計算しているため(pixman の制限っぽい?), 32768 が最大になります.
また, poppler だと指定解像度(-scale-to-x
など)に必ずしもマッチした解像度の画像が生成されないときもあります(aspect ratio 計算で誤差が出ている?)
Skia?
Python の skia binding で 64K x 64K まで Canvas 生成確認できました!
ただし PNG 保存だとエンコードに時間かかります
(fpng_py https://github.com/K0lb3/fpng_py など fpng バインディングだと, 解像度多いと fpng が対応できていないのかクラッシュする)
SVG, PDF 読み込み?
Skia では SVG, PDF の読み込みはサポートしていません. なにか方法を考える必要があります.
.NET だと svg バインディングがあるようであるが...
React native skia とか pdfjs + cairo backend で JS レイヤーで PDF ラスタライズできたりするじゃろか?
(また, 通常ブラウザ動作(HTML5 描画)だと canvas は 8K くらいまで)
Flutter ならいけるかもだけど, Flutter セットアップめんどいじゃ
svg-native-viewer が C++ で Skia backend で使っているので, svg-native-viewer いけるかもしれません.
blend2d
できたてほやほやですが, svg を blend2d で処理する svg2b2d がありました.
ただ微調整はできなさそうです.
とりあえずは DotNet の Svg.Skia 使うのがよいかもしれません.
画面分割?
4K とかのタイルに分けて処理して最後繋ぐという手もあります.
ただ, poppler ではオフセットかけてラスタライズというのは無いっぽいようです...
python + cairosvg とかで頑張ればいけるかもはしれません.
また, タイル間でラスタライズのずれのアーティストがでるかもしれません.
TODO
- python-skia で SVG, PDF 読み込みのいい方法を探す.
Discussion