何を見つけたか
base コンテナに、Office 文書を画像へ描画する経路が1つも無い。 document-skills(pptx / docx / xlsx / pdf)の視覚 QA は soffice --headless --convert-to pdf で PDF にし、pdftoppm で画像にする手順だが、その両方が入っていない。
devbase-base:latest(Ubuntu 26.04 / arm64)での実測。
| コマンド / モジュール |
状態 |
soffice / libreoffice |
なし |
pdftoppm / pdftocairo |
なし |
gs / convert / mutool / qpdf |
なし |
python3 の PIL / defusedxml / lxml |
なし |
pip / pip3 |
なし(uv はある) |
gws(@googleworkspace/cli) |
あり |
そのため、スライドを作っても出来上がりを目視で確認できない。 文字のはみ出し・要素の重なり・表と枠の衝突は、レンダリングしないと分からない。
どこで見つけたか
volareinc/nyle-dx の PR #5(経営会議向けスライド11ページ)を作る過程。既存の document-skills:pptx の QA 手順が丸ごと通らなかったため、Google Slides へ変換して gws slides presentations pages getThumbnail でサムネイルを取るという迂回で凌いだ。
この迂回は結果的に精度が高い(配布する実物を見るため、フォント代替による幅ズレが起きない)が、Google アカウントとネットワークが要る。 オフラインでも文書を作る作業では通らない。
実測
追加サイズ
devbase-base:latest は 7.09GB(docker images のディスク使用量。コンテンツのサイズは 2.04GB)。これに対する比率を併記する。
下の追加サイズは起票時に Ubuntu 26.04 / arm64 の apt-get install --no-install-recommends の依存解決から算出した値で、その後のイメージのビルドでは再測していない。
| セット |
追加パッケージ |
展開 |
ダウンロード |
base 比 |
poppler-utils |
14 |
9.0 MB |
2.7 MB |
+0.1% |
python3-pil python3-defusedxml python3-lxml |
18 |
12.2 MB |
3.4 MB |
+0.2% |
libreoffice-impress のみ |
78 |
372.1 MB |
101.8 MB |
+5.2% |
libreoffice-impress + -writer + -calc |
90 |
458.6 MB |
122.7 MB |
+6.5% |
libreoffice(メタ) |
98 |
475.0 MB |
126.4 MB |
+6.7% |
fonts-crosextra-carlito + -caladea |
2 |
3.0 MB |
0.9 MB |
+0.04% |
大きいのは libreoffice-core 149.9 MB、libreoffice-common 46.5 MB、libicu78 38.0 MB、iso-codes 23.5 MB。libreoffice メタと impress+writer+calc の差は 16 MB しかない。
提案する 6 パッケージは Ubuntu 26.04 arm64 にすべて存在する(poppler-utils 26.01.0-2ubuntu0.1 / python3-pil 12.1.1-2ubuntu1.3 / python3-defusedxml 0.7.1-3build1 / python3-lxml 6.0.2-1build1 / fonts-crosextra-carlito 20230309-2 / fonts-crosextra-caladea 20200211-2)。
動作の検証
poppler-utils python3-pil python3-defusedxml python3-lxml libreoffice-impress を稼働中のコンテナへ入れて(イメージではない)、11ページの日本語スライドで通した。
$ soffice --headless --norestore --convert-to pdf deck.pptx
convert deck.pptx as a Impress document -> deck.pdf using filter : impress_pdf_Export
real 0m0.616s
$ pdfinfo deck.pdf | grep Pages
Pages: 11
$ pdftoppm -jpeg -r 100 deck.pdf slide && ls slide-*.jpg | wc -l
11
通った。 画像も日本語が正しく出た。追加された展開サイズの実測は 381.8 MB(86パッケージ)。
フォント代替が起きる
指定した書体がコンテナに無いと、字幅の違う書体へ置き換わる。 今回のスライドは Zen Kaku Gothic New を指定していたが、PDF に埋め込まれたのは NotoSansCJKsc だった。
$ pdffonts deck.pdf
CAAAAA+NotoSansCJKsc-Bold Type 1 Builtin yes yes yes
DAAAAA+NotoSansCJKsc-Regular Type 1 Builtin yes yes yes
sc は簡体字中国語のフェイスである。 日本語の資料でも、既定では JP ではなく SC へ落ちる
- 字幅が違うため、Google Slides の実物では1行に収まっていた表の見出しが、この描画では2行に折り返した。「はみ出している」という QA の判定が実物と一致しない
document-skills:pptx の Typography 節は「代替フォントの幅が違うため QA の text-fit は当てにならない」と警告しており、その状態がそのまま起きる。
欧文側も同じである。 同 skill が「安全」とする Calibri と Cambria の metric 互換フォント(fonts-crosextra-carlito / fonts-crosextra-caladea)が入っていない。この2つは合計 3.0 MB で、入れると欧文の折り返し判定が信用できるようになる。fonts-liberation(Arial / Times New Roman の互換)は既に入っている。
markitdown は焼き込まなくてよい
内容の QA(markitdown deck.pptx)は uv で賄える。base に uv があるため追加は要らない(containers/base/Dockerfile の 135 行目と 189 行目で astral.sh から導入している)。
$ uvx --from 'markitdown[pptx]' markitdown deck.pptx
Installed 24 packages in 25ms
<!-- Slide number: 1 -->
初回だけ約45MB を取得する(numpy と onnxruntime が大きい)。2回目以降はキャッシュが効く。焼き込むと展開で 200MB 前後になるため、uvx のままがよい。
python3-pptx は apt に無い。必要になったら uv で入れる。
何をするか
LibreOffice は base に入れない(決定)。 展開 372〜459 MB は base の規律に見合わない。上の実測は、その判断の材料として残す。
base へ入れるもの
poppler-utils
python3-pil python3-defusedxml python3-lxml
fonts-crosextra-carlito fonts-crosextra-caladea
展開 約24 MB / ダウンロード 約7 MB、7.09GB の base に対して +0.34%。
| パッケージ |
何ができるようになるか |
poppler-utils |
PDF を画像にする。PDF のページ数・寸法・埋め込み書体を調べる(pdfinfo / pdffonts)。Office 文書に限らず出る作業 |
python3-pil python3-defusedxml python3-lxml |
document-skills の clean.py と office/validate.py が動く。OOXML を壊さずに読み書きできる(defusedxml を使わないと名前空間が壊れる) |
fonts-crosextra-carlito -caladea |
Calibri / Cambria の metric 互換フォント。欧文の字幅が正しくなる。fonts-liberation(Arial / Times 互換)は既に入っている |
thumbnail.py はこれだけでは動かない。 office.soffice.run_soffice を import して LibreOffice を必ず呼ぶため、LibreOffice を base に入れない以上、動くのは派生イメージ(下の案 A)の側である。clean.py と office/validate.py は soffice を参照しないので base で動く。
pip は足さない。uv があるため、必要な Python パッケージはそちらで賄う。
Office 文書を画像にする経路をどうするか
base に入れない以上、この経路は base の外に置く。 候補は3つある。
| 案 |
形 |
base への負担 |
制約 |
| A |
派生イメージに置く(containers/docs を新設、または containers/latex を文書系として広げる) |
0。そのプロジェクトだけが払う |
containers/latex が同じ形の先例(FROM devbase-base:latest + TeX Live) |
| B |
使い捨てコンテナで都度変換する |
0。初回だけ pull |
base に docker-ce があるため成立する。イメージの選定と保守が要る |
| C |
Google Slides へ変換して確認する |
0 |
gws(@googleworkspace/cli)が base にある。Google アカウントとネットワークが要る |
A を推す。 containers/latex という先例があり(containers/latex/Dockerfile:7 が FROM devbase-base:latest)、文書を作るプロジェクトだけが 372〜459 MB を払う形になる。devbase build <image> は $DEVBASE_ROOT/containers/<image> を汎用に建ててタグを devbase-<ディレクトリ名> にするため、containers/docs の新設に本体側の登録変更は要らない。
C はサイズ 0 で、しかも精度が高い。 配布する実物を見るため、書体の代替による字幅のずれが起きない。ただし Google アカウントが要るため、単独の解にはならない。実案件(volareinc/nyle-dx PR #5)ではこの手で11ページを確認した。
前提として直したいこと
日本語が中国語のフォントで描画される問題が別にある(#161)。 fc-match sans-serif:lang=ja が WenQuanYi Zen Hei を返す状態は v3.6.0 の base イメージでも再現する。この状態では、どの経路で描画しても日本語の字形と字幅が正しくない。 追加パッケージ 0(/etc/fonts/local.conf を1つ置く)で直り、検証済みである。描画の道具を足す前に、こちらを先に直したい。
#161 と本件は containers/base/Dockerfile の同じ apt / COPY の区画を触る。#161 を先に入れるか、1 本の PR にまとめる。
修正レイヤー
現象レイヤー: スライドや文書を作っても出来上がりを目視で確認できない(document-skills の QA 手順が丸ごと通らない)。
修正レイヤー: 2 層に分かれる。
| 層 |
対象 |
直す場所 |
| 軽量の道具 |
poppler-utils / python3-pil / python3-defusedxml / python3-lxml / crosextra 2 種 |
containers/base/Dockerfile の apt 行 |
| Office から画像への経路 |
LibreOffice |
base の外。containers/docs の新設(containers/latex と同じ FROM devbase-base:latest の形) |
採る手: 新設(containers/docs)。軽量の道具の側は既存の apt 行への追加で、層の移動は伴わない。
由来
volareinc/nyle-dx PR #5 / devbasex/ai-plugins #530
進行
モード: standard / 作業ツリー: .worktrees/design/v3.7.0-base-rendering / 計画: issues/PLAN63_base-image-rendering-design.md
何を見つけたか
base コンテナに、Office 文書を画像へ描画する経路が1つも無い。
document-skills(pptx / docx / xlsx / pdf)の視覚 QA はsoffice --headless --convert-to pdfで PDF にし、pdftoppmで画像にする手順だが、その両方が入っていない。devbase-base:latest(Ubuntu 26.04 / arm64)での実測。soffice/libreofficepdftoppm/pdftocairogs/convert/mutool/qpdfPIL/defusedxml/lxmlpip/pip3uvはある)gws(@googleworkspace/cli)そのため、スライドを作っても出来上がりを目視で確認できない。 文字のはみ出し・要素の重なり・表と枠の衝突は、レンダリングしないと分からない。
どこで見つけたか
volareinc/nyle-dxの PR #5(経営会議向けスライド11ページ)を作る過程。既存のdocument-skills:pptxの QA 手順が丸ごと通らなかったため、Google Slides へ変換してgws slides presentations pages getThumbnailでサムネイルを取るという迂回で凌いだ。この迂回は結果的に精度が高い(配布する実物を見るため、フォント代替による幅ズレが起きない)が、Google アカウントとネットワークが要る。 オフラインでも文書を作る作業では通らない。
実測
追加サイズ
devbase-base:latestは 7.09GB(docker imagesのディスク使用量。コンテンツのサイズは 2.04GB)。これに対する比率を併記する。下の追加サイズは起票時に Ubuntu 26.04 / arm64 の
apt-get install --no-install-recommendsの依存解決から算出した値で、その後のイメージのビルドでは再測していない。poppler-utilspython3-pilpython3-defusedxmlpython3-lxmllibreoffice-impressのみlibreoffice-impress+-writer+-calclibreoffice(メタ)fonts-crosextra-carlito+-caladea大きいのは
libreoffice-core149.9 MB、libreoffice-common46.5 MB、libicu7838.0 MB、iso-codes23.5 MB。libreofficeメタとimpress+writer+calcの差は 16 MB しかない。提案する 6 パッケージは Ubuntu 26.04 arm64 にすべて存在する(
poppler-utils26.01.0-2ubuntu0.1 /python3-pil12.1.1-2ubuntu1.3 /python3-defusedxml0.7.1-3build1 /python3-lxml6.0.2-1build1 /fonts-crosextra-carlito20230309-2 /fonts-crosextra-caladea20200211-2)。動作の検証
poppler-utilspython3-pilpython3-defusedxmlpython3-lxmllibreoffice-impressを稼働中のコンテナへ入れて(イメージではない)、11ページの日本語スライドで通した。通った。 画像も日本語が正しく出た。追加された展開サイズの実測は 381.8 MB(86パッケージ)。
フォント代替が起きる
指定した書体がコンテナに無いと、字幅の違う書体へ置き換わる。 今回のスライドは
Zen Kaku Gothic Newを指定していたが、PDF に埋め込まれたのはNotoSansCJKscだった。scは簡体字中国語のフェイスである。 日本語の資料でも、既定では JP ではなく SC へ落ちるdocument-skills:pptxの Typography 節は「代替フォントの幅が違うため QA の text-fit は当てにならない」と警告しており、その状態がそのまま起きる。欧文側も同じである。 同 skill が「安全」とする Calibri と Cambria の metric 互換フォント(
fonts-crosextra-carlito/fonts-crosextra-caladea)が入っていない。この2つは合計 3.0 MB で、入れると欧文の折り返し判定が信用できるようになる。fonts-liberation(Arial / Times New Roman の互換)は既に入っている。markitdownは焼き込まなくてよい内容の QA(
markitdown deck.pptx)はuvで賄える。base にuvがあるため追加は要らない(containers/base/Dockerfileの 135 行目と 189 行目で astral.sh から導入している)。初回だけ約45MB を取得する(
numpyとonnxruntimeが大きい)。2回目以降はキャッシュが効く。焼き込むと展開で 200MB 前後になるため、uvxのままがよい。python3-pptxは apt に無い。必要になったらuvで入れる。何をするか
LibreOffice は base に入れない(決定)。 展開 372〜459 MB は base の規律に見合わない。上の実測は、その判断の材料として残す。
base へ入れるもの
展開 約24 MB / ダウンロード 約7 MB、7.09GB の base に対して +0.34%。
poppler-utilspdfinfo/pdffonts)。Office 文書に限らず出る作業python3-pilpython3-defusedxmlpython3-lxmldocument-skillsのclean.pyとoffice/validate.pyが動く。OOXML を壊さずに読み書きできる(defusedxmlを使わないと名前空間が壊れる)fonts-crosextra-carlito-caladeafonts-liberation(Arial / Times 互換)は既に入っているthumbnail.pyはこれだけでは動かない。office.soffice.run_sofficeを import して LibreOffice を必ず呼ぶため、LibreOffice を base に入れない以上、動くのは派生イメージ(下の案 A)の側である。clean.pyとoffice/validate.pyはsofficeを参照しないので base で動く。pipは足さない。uvがあるため、必要な Python パッケージはそちらで賄う。Office 文書を画像にする経路をどうするか
base に入れない以上、この経路は base の外に置く。 候補は3つある。
containers/docsを新設、またはcontainers/latexを文書系として広げる)containers/latexが同じ形の先例(FROM devbase-base:latest+ TeX Live)docker-ceがあるため成立する。イメージの選定と保守が要るgws(@googleworkspace/cli)が base にある。Google アカウントとネットワークが要るA を推す。
containers/latexという先例があり(containers/latex/Dockerfile:7がFROM devbase-base:latest)、文書を作るプロジェクトだけが 372〜459 MB を払う形になる。devbase build <image>は$DEVBASE_ROOT/containers/<image>を汎用に建ててタグをdevbase-<ディレクトリ名>にするため、containers/docsの新設に本体側の登録変更は要らない。C はサイズ 0 で、しかも精度が高い。 配布する実物を見るため、書体の代替による字幅のずれが起きない。ただし Google アカウントが要るため、単独の解にはならない。実案件(
volareinc/nyle-dxPR #5)ではこの手で11ページを確認した。前提として直したいこと
日本語が中国語のフォントで描画される問題が別にある(#161)。
fc-match sans-serif:lang=jaがWenQuanYi Zen Heiを返す状態は v3.6.0 の base イメージでも再現する。この状態では、どの経路で描画しても日本語の字形と字幅が正しくない。 追加パッケージ 0(/etc/fonts/local.confを1つ置く)で直り、検証済みである。描画の道具を足す前に、こちらを先に直したい。#161 と本件は
containers/base/Dockerfileの同じ apt / COPY の区画を触る。#161 を先に入れるか、1 本の PR にまとめる。修正レイヤー
現象レイヤー: スライドや文書を作っても出来上がりを目視で確認できない(
document-skillsの QA 手順が丸ごと通らない)。修正レイヤー: 2 層に分かれる。
poppler-utils/python3-pil/python3-defusedxml/python3-lxml/ crosextra 2 種containers/base/Dockerfileの apt 行containers/docsの新設(containers/latexと同じFROM devbase-base:latestの形)採る手: 新設(
containers/docs)。軽量の道具の側は既存の apt 行への追加で、層の移動は伴わない。由来
volareinc/nyle-dxPR #5 /devbasex/ai-plugins#530進行
モード: standard / 作業ツリー:
.worktrees/design/v3.7.0-base-rendering/ 計画:issues/PLAN63_base-image-rendering-design.md