html2canvas vs html-to-image vs dom-to-image
HTML要素を画像に変換するライブラリの比較
html2canvashtml-to-imagedom-to-image類似パッケージ:

HTML要素を画像に変換するライブラリの比較

dom-to-imagehtml-to-imagehtml2canvas はいずれもブラウザ上でHTML要素を画像(PNGやJPEGなど)に変換するためのJavaScriptライブラリです。これらはスクリーンショット機能、レポート生成、コンテンツ共有などのユースケースで広く使われます。dom-to-imagehtml-to-image はSVGベースのアプローチを採用し、CSSスタイルやフォントをより正確に再現します。一方、html2canvas はCanvas APIを直接利用して描画をシミュレートし、複雑なDOM構造にも対応しますが、一部のCSSプロパティや外部リソースの処理に制限があります。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
html2canvas8,738,25731,8213.38 MB1,047-MIT
html-to-image2,354,5887,060315 kB1911年前MIT
dom-to-image238,13210,786-3378年前MIT

HTML要素を画像に変換するライブラリ:dom-to-image vs html-to-image vs html2canvas

フロントエンド開発で「画面の一部を画像として保存したい」という要件はよくあります。例えば、グラフの共有、レポート出力、ユーザー生成コンテンツのプレビューなどです。そのようなニーズを満たす代表的なnpmパッケージが dom-to-imagehtml-to-imagehtml2canvas です。これらは似た目的を持ちますが、内部実装、対応範囲、メンテナンス状況に大きな違いがあります。この記事では、実際のコード例を交えながら、各ライブラリの特性と選定基準を解説します。

⚠️ メンテナンス状況:非推奨かどうかが重要

まず最初に確認すべきは、パッケージが現在もアクティブにメンテナンスされているかです。

  • dom-to-imagenpmページ および GitHubリポジトリ で明確に 非推奨(deprecated) とされています。作者は後継として html-to-image を推奨しています。新規プロジェクトでの使用は避けてください。

  • html-to-imagedom-to-image のフォークであり、GitHubリポジトリ は活発に更新されており、TypeScript定義やモダンなツールチェーンをサポートしています。

  • html2canvas は長年利用されてきた成熟したライブラリで、公式サイト も整備されており、定期的に更新されています。

💡 新規プロジェクトでは、dom-to-image は選択肢から外しましょう。

🖼️ 基本的な使い方:10行で画像生成

各ライブラリの基本的な使い方を比較します。対象は <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-image

import { 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);
  });

html2canvas

import html2canvas from 'html2canvas';

const node = document.getElementById('capture');
html2canvas(node).then(canvas => {
  const img = new Image();
  img.src = canvas.toDataURL();
  document.body.appendChild(img);
});

見た目は似ていますが、内部の処理は大きく異なります。

🔧 内部実装:SVG vs Canvas

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-shadowtransformfilter などの一部CSSプロパティが正しく描画されない
  • 外部ドメインの画像やフォントはCORS設定がないと表示されない
  • 動的なCanvasやWebGLコンテンツはキャプチャ不可

🎨 スタイルとフォントの再現性

Webフォントの扱い

html-to-image は、fontEmbedCss オプションでGoogle FontsなどのWebフォントを自動埋め込みます。

import { toPng } from 'html-to-image';

toPng(node, {
  fontEmbedCss: true // デフォルトで有効
});

一方、html2canvasuseCORS: true オプションを指定することで、CORSヘッダー付きのフォント/画像を読み込もうとしますが、サーバー側の設定が必須です。

html2canvas(node, {
  useCORS: true
});

複雑なCSS(例:clip-path

clip-pathmask といった高度なCSSプロパティは、html-to-image ではSVG互換のもののみ動作し、html2canvas では未対応です。どちらも完全な再現は難しいため、事前に検証が必要です。

📦 オプションとカスタマイズ性

画像形式と品質

  • html-to-imagetoPng()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);
});

要素の除外や変更

html2canvasignoreElements オプションで特定の要素を除外できます。

html2canvas(node, {
  ignoreElements: (el) => el.classList.contains('no-screenshot')
});

html-to-imageskipFontscacheBust などの細かい制御が可能ですが、要素単位の除外はできません。代わりに、一時的にDOMを操作してからキャプチャする必要があります。

🚀 パフォーマンスと大規模DOM

  • 小〜中規模DOM(例:カード、チャート):html-to-image が高速で軽量。
  • 大規模DOM(例:長文ドキュメント、ダッシュボード):html2canvas がより安定。ただし、描画時間がかかる場合あり。

html2canvasscale オプションで解像度を調整でき、高DPIディスプレイ向けに高品質画像を生成可能です。

html2canvas(node, {
  scale: 2 // 通常の2倍の解像度
});

🔄 実際の開発シーンでの選定ガイド

ケース1:シンプルなUIカードをPNGで共有

  • 推奨: html-to-image
  • 理由: 軽量、CSS再現性が高い、APIが直感的
import { 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();
};

ケース2:iframeを含むダッシュボード全体をキャプチャ

  • html-to-image はiframe非対応
  • 推奨: html2canvas(ただしiframe内は空白になる)
  • 注意: iframe内のコンテンツは別途キャプチャして合成する必要がある

ケース3:アニメーション中のCanvas要素を含むゲーム画面

  • ❌ いずれのライブラリも動的Canvasの内容を直接キャプチャできない
  • 対応策: Canvas自体を toDataURL() で取得し、別途合成

📌 まとめ:各ライブラリの特徴

特徴dom-to-imagehtml-to-imagehtml2canvas
メンテナンス状況非推奨アクティブアクティブ
内部実装SVG → CanvasSVG → CanvasCanvas再現
Webフォント対応△(手動対応必要)◯(自動埋め込み)△(CORS必須)
iframe対応△(空白になる)
複雑CSS対応△(SVG互換のみ)△(SVG互換のみ)✕(多くのプロパティ未対応)
大規模DOM
軽量さ△(やや重め)

💡 最終的なアドバイス

  • 新規プロジェクトでは、まず html-to-image を試してください。シンプルで再現性が高く、TypeScript対応も万全です。
  • 複雑なレイアウトや大量のDOM要素がある場合は、html2canvas の挙動を検証しましょう。特に、CSSの制限を事前に把握することが重要です。
  • dom-to-image は絶対に新規で使わないでください。既存コードがある場合も、可能なら html-to-image への移行を検討しましょう。

どのライブラリを選ぶにせよ、実際のターゲット環境(ブラウザ、OS、DPR)で必ずテストすることを忘れないでください。画像の再現性は環境によって大きく変わるためです。

選び方: html2canvas vs html-to-image vs dom-to-image

  • html2canvas:

    html2canvas はCanvas APIを用いてDOMを描画するため、iframeや動的コンテンツ、複雑なレイアウトを含むページでも比較的高い忠実度でスクリーンショットを取得できます。ただし、CSSの一部(例:mix-blend-modeclip-path)や外部フォントの読み込みに制限があり、結果がブラウザネイティブのスクリーンショットと異なる場合があります。大規模なDOMやアニメーション付き要素のキャプチャが必要な場合に有力な選択肢です。

  • html-to-image:

    html-to-imagedom-to-image の後継として開発されており、同じSVGベースのアプローチを維持しながら、TypeScriptサポートやモダンなビルド環境、バグ修正を提供しています。CSSスタイルやWebフォントの再現性が高く、軽量で使いやすいAPIを求める場合に最適です。ただし、iframeや動的なCanvas要素など、高度なレンダリングには対応していません。

  • dom-to-image:

    dom-to-image はシンプルなDOM要素の画像化に適していますが、公式には非推奨(deprecated)とされています。新しいプロジェクトでは使用せず、代わりに後継である html-to-image を検討してください。既存プロジェクトで安定稼働している場合は、移行コストを考慮しつつ保守運用を続ける選択肢もありますが、新規開発では避けるべきです。

html2canvas のREADME

html2canvas

Homepage | Downloads | Questions

Gitter CI NPM Downloads NPM Version

JavaScript HTML renderer

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.

How does it work?

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.

Browser compatibility

The library should work fine on the following browsers (with Promise polyfill):

  • Firefox 3.5+
  • Google Chrome
  • Opera 12+
  • IE9+
  • Safari 6+

As each CSS property needs to be manually built to be supported, there are a number of properties that are not yet supported.

Usage

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);
});

Building

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

Examples

For more information and examples, please visit the homepage or try the test console.

Contributing

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.