dom-to-image、html-to-image、html2canvas はいずれもブラウザ上でHTML要素を画像(PNGやJPEGなど)に変換するためのJavaScriptライブラリです。これらはスクリーンショット機能、レポート生成、コンテンツ共有などのユースケースで広く使われます。dom-to-image と html-to-image はSVGベースのアプローチを採用し、CSSスタイルやフォントをより正確に再現します。一方、html2canvas はCanvas APIを直接利用して描画をシミュレートし、複雑なDOM構造にも対応しますが、一部のCSSプロパティや外部リソースの処理に制限があります。
フロントエンド開発で「画面の一部を画像として保存したい」という要件はよくあります。例えば、グラフの共有、レポート出力、ユーザー生成コンテンツのプレビューなどです。そのようなニーズを満たす代表的なnpmパッケージが dom-to-image、html-to-image、html2canvas です。これらは似た目的を持ちますが、内部実装、対応範囲、メンテナンス状況に大きな違いがあります。この記事では、実際のコード例を交えながら、各ライブラリの特性と選定基準を解説します。
まず最初に確認すべきは、パッケージが現在もアクティブにメンテナンスされているかです。
dom-to-image は npmページ および GitHubリポジトリ で明確に 非推奨(deprecated) とされています。作者は後継として html-to-image を推奨しています。新規プロジェクトでの使用は避けてください。
html-to-image は dom-to-image のフォークであり、GitHubリポジトリ は活発に更新されており、TypeScript定義やモダンなツールチェーンをサポートしています。
html2canvas は長年利用されてきた成熟したライブラリで、公式サイト も整備されており、定期的に更新されています。
💡 新規プロジェクトでは、
dom-to-imageは選択肢から外しましょう。
各ライブラリの基本的な使い方を比較します。対象は <div id="capture">Hello World</div> という要素とします。
dom-to-image(非推奨)import domtoimage from 'dom-to-image';
const node = document.getElementById('capture');
domtoimage.toPng(node)
.then(dataUrl => {
const img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
});
html-to-imageimport { toPng } from 'html-to-image';
const node = document.getElementById('capture');
toPng(node)
.then(dataUrl => {
const img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
});
html2canvasimport html2canvas from 'html2canvas';
const node = document.getElementById('capture');
html2canvas(node).then(canvas => {
const img = new Image();
img.src = canvas.toDataURL();
document.body.appendChild(img);
});
見た目は似ていますが、内部の処理は大きく異なります。
dom-to-image / html-to-image:SVG経由の描画これらのライブラリは、DOM要素を一時的にSVGに変換し、そのSVGをCanvasに描画して画像データURLを生成します。この方式の利点は、CSSスタイルやWebフォントを比較的正確に再現できることです。
// html-to-image の内部処理イメージ
// 1. DOM → SVG文字列(インラインスタイル付き)
// 2. SVGをBlob URLに変換
// 3. そのURLをImage要素で読み込み
// 4. Canvasに描画 → toDataURL()
ただし、iframe、動的Canvas、video要素などはサポートされません。また、CORSで保護された外部画像は描画されない可能性があります。
html2canvas:CanvasによるDOM再現html2canvas はブラウザのレンダリングエンジンを模倣し、Canvas APIを使ってDOMノードを1つずつ描画します。つまり、実際のスクリーンショットではなく「再現」 です。
この方式の利点は、iframe以外のほとんどのHTML要素を扱えることです。ただし、以下の制限があります:
box-shadow、transform、filter などの一部CSSプロパティが正しく描画されないhtml-to-image は、fontEmbedCss オプションでGoogle FontsなどのWebフォントを自動埋め込みます。
import { toPng } from 'html-to-image';
toPng(node, {
fontEmbedCss: true // デフォルトで有効
});
一方、html2canvas は useCORS: true オプションを指定することで、CORSヘッダー付きのフォント/画像を読み込もうとしますが、サーバー側の設定が必須です。
html2canvas(node, {
useCORS: true
});
clip-path)clip-path や mask といった高度なCSSプロパティは、html-to-image ではSVG互換のもののみ動作し、html2canvas では未対応です。どちらも完全な再現は難しいため、事前に検証が必要です。
html-to-image は toPng()、toJpeg()、toSvg()、toCanvas() を提供。JPEGでは品質調整可能。// JPEGで品質80%
toJpeg(node, { quality: 0.8 });
html2canvas は常にCanvasを返すため、toDataURL('image/jpeg', 0.8) で形式と品質を指定。html2canvas(node).then(canvas => {
const dataUrl = canvas.toDataURL('image/jpeg', 0.8);
});
html2canvas は ignoreElements オプションで特定の要素を除外できます。
html2canvas(node, {
ignoreElements: (el) => el.classList.contains('no-screenshot')
});
html-to-image は skipFonts や cacheBust などの細かい制御が可能ですが、要素単位の除外はできません。代わりに、一時的にDOMを操作してからキャプチャする必要があります。
html-to-image が高速で軽量。html2canvas がより安定。ただし、描画時間がかかる場合あり。html2canvas は scale オプションで解像度を調整でき、高DPIディスプレイ向けに高品質画像を生成可能です。
html2canvas(node, {
scale: 2 // 通常の2倍の解像度
});
html-to-imageimport { toPng } from 'html-to-image';
const download = async () => {
const dataUrl = await toPng(document.getElementById('card'));
const link = document.createElement('a');
link.download = 'card.png';
link.href = dataUrl;
link.click();
};
html-to-image はiframe非対応html2canvas(ただしiframe内は空白になる)toDataURL() で取得し、別途合成| 特徴 | dom-to-image | html-to-image | html2canvas |
|---|---|---|---|
| メンテナンス状況 | 非推奨 | アクティブ | アクティブ |
| 内部実装 | SVG → Canvas | SVG → Canvas | Canvas再現 |
| Webフォント対応 | △(手動対応必要) | ◯(自動埋め込み) | △(CORS必須) |
| iframe対応 | ✕ | ✕ | △(空白になる) |
| 複雑CSS対応 | △(SVG互換のみ) | △(SVG互換のみ) | ✕(多くのプロパティ未対応) |
| 大規模DOM | △ | △ | ◯ |
| 軽量さ | ◯ | ◯ | △(やや重め) |
html-to-image を試してください。シンプルで再現性が高く、TypeScript対応も万全です。html2canvas の挙動を検証しましょう。特に、CSSの制限を事前に把握することが重要です。dom-to-image は絶対に新規で使わないでください。既存コードがある場合も、可能なら html-to-image への移行を検討しましょう。どのライブラリを選ぶにせよ、実際のターゲット環境(ブラウザ、OS、DPR)で必ずテストすることを忘れないでください。画像の再現性は環境によって大きく変わるためです。
html2canvas はCanvas APIを用いてDOMを描画するため、iframeや動的コンテンツ、複雑なレイアウトを含むページでも比較的高い忠実度でスクリーンショットを取得できます。ただし、CSSの一部(例:mix-blend-mode や clip-path)や外部フォントの読み込みに制限があり、結果がブラウザネイティブのスクリーンショットと異なる場合があります。大規模なDOMやアニメーション付き要素のキャプチャが必要な場合に有力な選択肢です。
html-to-image は dom-to-image の後継として開発されており、同じSVGベースのアプローチを維持しながら、TypeScriptサポートやモダンなビルド環境、バグ修正を提供しています。CSSスタイルやWebフォントの再現性が高く、軽量で使いやすいAPIを求める場合に最適です。ただし、iframeや動的なCanvas要素など、高度なレンダリングには対応していません。
dom-to-image はシンプルなDOM要素の画像化に適していますが、公式には非推奨(deprecated)とされています。新しいプロジェクトでは使用せず、代わりに後継である html-to-image を検討してください。既存プロジェクトで安定稼働している場合は、移行コストを考慮しつつ保守運用を続ける選択肢もありますが、新規開発では避けるべきです。
Homepage | Downloads | Questions
The script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
The script renders the current page as a canvas image, by reading the DOM and the different styles applied to the elements.
It does not require any rendering from the server, as the whole image is created on the client's browser. However, as it is heavily dependent on the browser, this library is not suitable to be used in nodejs. It doesn't magically circumvent any browser content policy restrictions either, so rendering cross-origin content will require a proxy to get the content to the same origin.
The script is still in a very experimental state, so I don't recommend using it in a production environment nor start building applications with it yet, as there will be still major changes made.
The library should work fine on the following browsers (with Promise polyfill):
As each CSS property needs to be manually built to be supported, there are a number of properties that are not yet supported.
The html2canvas library utilizes Promises and expects them to be available in the global context. If you wish to
support older browsers that do not natively support Promises, please include a polyfill such as
es6-promise before including html2canvas.
To render an element with html2canvas, simply call:
html2canvas(element[, options]);
The function returns a Promise containing the <canvas> element. Simply add a promise fulfillment handler to the promise using then:
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
You can download ready builds here.
Clone git repository:
$ git clone git://github.com/niklasvh/html2canvas.git
Install dependencies:
$ npm install
Build browser bundle
$ npm run build
For more information and examples, please visit the homepage or try the test console.
If you wish to contribute to the project, please send the pull requests to the develop branch. Before submitting any changes, try and test that the changes work with all the support browsers. If some CSS property isn't supported or is incomplete, please create appropriate tests for it as well before submitting any code changes.