HTML の Element を画像に変換するライブラリ dom-to-image を試しました。Chrome では良好ですが、Firefox では文字のサイズが変わってはみ出すようです。
See the Pen Test: dom-to-image by 七誌 (@7shi) on CodePen.
↑ 左が撮影元の Element、右がそれを画像化したものです。内容はデザインでよく使われる lorem ipsum と呼ばれるダミーテキストで、意味はありません。
シリーズの記事です。
- dom-to-imageを試す ← 今回の記事
- html2canvasを試す
- 複数の画像を生成してローカルに保存
dom-to-image
リポジトリ: tsayen/dom-to-image: Generates an image from a DOM node using HTML5 canvas
画像に変換する方法は README に説明があります。DeepL で翻訳したものに手を加えて引用します。
このライブラリは SVG の
<foreignObject>
タグの中に任意の HTML コンテンツを入れることができる機能を使っています。そして、その DOM ノードをレンダリングするためには、以下の手順を踏む必要があります。
元の DOM ノードを再帰的にクローン
ノードと各サブノードのスタイルを計算して、対応するクローンにコピー
- 疑似要素の再作成を忘れないでください。それらはどのような方法でもクローンされません。
- ウェブフォントを埋め込む
- ウェブフォントを表す可能性のある
@font-face
宣言をすべて探す- ファイルの URL を解析して、対応するファイルをダウンロード
- base64 エンコードして、コンテンツを
data:
で表される URL としてインライン化- 処理されたすべての CSS ルールを連結して1つの
<style>
要素にまとめ、それをクローンにアタッチ
- 画像を埋め込む
<img>
要素に画像 URL を埋め込む- CSS の
background
プロパティで使用される画像を、フォントと同様の方法でインライン化
クローンされたノードを XML にシリアライズ
XML を
<foreignObject>
タグにラップして SVG に入れて、データ URL を作成オプションで、PNG コンテンツや生のピクセルデータを Uint8Array として取得するには、SVG をソースとして Image 要素を作成して、オフスクリーンで Canvas を作成してレンダリングし、Canvas からコンテンツを読み込む。
完成!
以下の記事ではライブラリを用いずにこの方法を説明しています。
利用方法
自前でどこかに置かなくても、jsDelivr 経由で参照できます。
<script src="https://cdn.jsdelivr.net/npm/dom-to-image@2.6.0/dist/dom-to-image.min.js"></script>
README のサンプルコードを元に async/await で書き換えます。
(async () => {
try {
let img = new Image();
img.src = await domtoimage.toPng(src);
dst.appendChild(img);
} catch (e) {
console.error("oops, something went wrong!", e);
}
})();
動作結果
この記事の冒頭に貼ったサンプルのスクリーンショットを見ます。
Chrome では下に少し余白ができますが、文字のサイズはそのままで画像化されます。
Firefox では文字のサイズが変わってしまうため、画像からはみ出してしまいます。
撮影対象がブラウザに依存するのでなければ、Chrome で利用するのが無難なようです。
Firefox
手動になってしまいますが、Firefox では対象の Element の右クリックで画像化できます。
- 右クリック → 要素を調査
- 開発ツールが表示される
- 選択されているノードを右クリック → ノードのスクリーンショットを撮影
- ダウンロードフォルダにスクリーンショットが生成
※ dom-to-image は自動化にメリットがあるとは思いますが…
なお、この方法は SVG の画像化にも利用できます。
参考
dom-to-image は以下の記事で知りました。