私が歌川です

@utgwkk が書いている

JavaScriptで任意のHTML要素を画像化する取り組みのメモ

表題のことについてちょっと調べていて、だいたい以下のようなアプローチに分類できそう、と思ってきたのでメモです。

SVGの <foreignObject> にHTMLを突っ込む

SVGには <foreignObject> という要素があり、SVG以外の要素を描画することができる。ここにHTMLを丸ごと突っ込んだ上でSVGを画像化する、というアプローチ。

html-to-imageというライブラリがこの方針で実装されている。単にforeignObjectに突っ込むだけだと、画像やフォントがうまく使われないので埋め込む、ということをやっていそう*1

SafariではforeignObjectの制約が強いためうまく動かない、ということがhtml-to-imageのREADMEに書いてある。Safariをターゲットとしないならこのアプローチでうまくいきそう。

レンダラーを再実装する

ブラウザのレンダラーと同様に、任意のDOM要素を画像化する部分を実装してしまおう、というアプローチ。この方法は実行環境によらずうまく動く可能性が高いものの、ブラウザと全く同じ描画結果になる保証はない。

html2canvas は、DOM要素を受け取って独自実装のレンダラーでcanvasに画像として書き出している。

vercel/satoriは、DOMのサブセットとスタイルを受け取ってSVGに変換 (ベクタ画像化) している。

画面キャプチャAPIを使う

developer.mozilla.org

画面キャプチャAPIを使って、ブラウザの画面を映し、それを画像化することができそう? ただし画像キャプチャAPI自体はモバイル端末には対応していない。

既存の画像生成アプリケーションをWASMにコンパイルしてブラウザ上で動かす

ぜんぜん調査できていないけど、たしかにそういう手法もありそう!!