画像をBase64に変換する方法
画像をBase64に変換すると、画像をHTML、CSS、JSONペイロードに直接埋め込むのに便利です。これにより、追加のHTTPリクエストが不要になり、コンテンツが自己完結型になります。<img> タグの src 属性がURLを指す外部画像ファイルにリンクする代わりに、データURIを使用して画像データをHTMLに直接埋め込むことができます。これにより、ブラウザが画像のために別途ネットワークリクエストを行う必要がなくなり、レイテンシが削減され、外部リソースがブロックされている場合でも画像が利用可能であることが保証されます。
画像のBase64エンコーディングの概念は、テキスト用に設計されたメディアを介してバイナリデータを送信する必要性に基づいています。メール、JSON、XML、および多くのWebプロトコルは、主にテキストコンテンツ用に設計されています。これらのコンテキストに画像のようなバイナリデータを含める必要がある場合、Base64エンコーディングはバイナリ画像データを安全なASCII表現に変換し、特別な処理なしでインラインに含めることができます。トレードオフは、元のバイナリファイルと比較して約33%のサイズ増加ですが、アイコン、ロゴ、サムネイルなどの小さな画像では、このオーバーヘッドは許容範囲であることが多いです。
データURIについて
データURIは、データをWebページにインラインで含めることを可能にするURLスキームです。画像データURIの形式は次のとおりです:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
データURIの構成要素は次のとおりです。data: プレフィックスは、コンテンツが外部URLからフェッチされるのではなくインラインであることをブラウザに伝えます。image/png の部分は画像形式を指定するMIMEタイプです。base64 キーワードは使用されるエンコーディング方式を示します。カンマ以降はすべてBase64エンコードされた画像データです。
ブラウザは、<img> タグ、CSSの background-image プロパティ、さらにはファビコンの <link rel="icon"> タグでもデータURIをサポートしています。ブラウザはBase64データをバイナリにデコードし、URLからフェッチされた場合とまったく同じように画像をレンダリングします。
Base64用の画像形式比較
Base64に変換する前に適切な画像形式を選択することで、結果のデータURIのファイルサイズと品質の両方に影響します。
| 形式 | 圧縮 | 最適な用途 | Base64サイズ増加 |
|---|---|---|---|
| PNG | 可逆圧縮 | グラフィック、アイコン、スクリーンショット | ~33% |
| JPEG | 非可逆圧縮 | 写真、複雑な画像 | ~33% |
| GIF | 可逆圧縮 | シンプルなアニメーション | ~33% |
| WebP | 両方 | モダンWeb(最小ファイル) | ~33% |
| SVG | テキストベース | ベクターグラフィック | 最小 |
Base64のサイズ増加は形式間で一貫しています。これは、Base64が入力の3バイトごとに4バイトの出力にエンコードし、必要に応じてパディングが追加されるためです。つまり、10 KBのPNGファイルはBase64エンコード後、画像形式に関係なく約13.6 KBになります。
ただし、画像形式の選択は開始サイズに劇的な影響を与えます。WebPは通常、同じ画質でPNGより25〜35%小さいファイルを生成します。Base64エンコードの前にPNGをWebPに変換すると、最終的なデータURIはPNGベースのデータURIよりも大幅に小さくなります。このため、Base64に変換する前に画像形式を最適化することは常に価値があります。
SVGは特殊なケースで、既にテキストベース(XML)です。SVGのPNGバージョンをBase64エンコードする代わりに、SVGマークアップをHTMLに直接含めることができます。これはBase64に変換するよりも効率的で、アクセシビリティが高く、柔軟性があります。別のHTTPリクエストを避けたいCSSの background-image プロパティなど、バイナリ形式が必要なコンテキストに埋め込む必要がある場合にのみ、SVGをBase64エンコードしてください。
Base64画像を使用するタイミング
画像をBase64データURIとして埋め込むことは、常に正しい選択とは限りません。いつ有益かを理解することで、情報に基づいたパフォーマンスの決定が可能になります。
推奨ユースケース
-
小さなアイコンとUI要素。 数百バイトから数キロバイトのアイコンは、Base64埋め込みに最適な候補です。各アイコンの個別のHTTPリクエストのオーバーヘッドは、Base64のサイズ増加をはるかに上回ります。通常のWebサイトには20〜50個の小さなアイコンがある場合があり、それらをデータURIとして埋め込むことで、数十のHTTPリクエストが不要になります。
-
CSSスプライトの代替。 CSSスプライト(多くの小さな画像を1つの大きな画像に結合し、background-positionを使用して適切な部分を表示する)の代わりに、各アイコンをBase64データURIとして埋め込むことができます。これによりCSSが簡素化され、スプライトアトラスを維持する必要がなくなります。
-
メール署名。 メールクライアントはデフォルトで外部画像をブロックすることがよくあります。画像をデータURIとして埋め込むことで、受信者のメールクライアントが外部コンテンツをブロックしても、ロゴや署名画像が常に表示されることが保証されます。
-
自己完結型ドキュメント。 レポート、プレゼンテーション、プロトタイプなど、配布用の単一ファイルHTMLドキュメントを作成する場合、すべての画像をデータURIとして埋め込むことでファイルが完全に自己完結型になります。受信者は外部アセットをダウンロードする必要がありません。
Base64画像を避けるべき場合
-
大きな写真。 500 KBのJPEGはBase64エンコード後700 KBになります。200 KBのオーバーヘッドは大きく、ブラウザはレンダリング前にBase64文字列をデコードする必要があるため、レイテンシが追加されます。大きな画像には、HTTPキャッシュを使用した標準の
<img>タグを使用してください。 -
同じページで複数回使用される画像。 同じ画像が複数回(ヘッダーとフッターのロゴなど)表示される場合、データURIは毎回埋め込まれ、バイトが重複します。キャッシュされた外部画像ファイルは1回フェッチされて再利用されます。
-
複数ページで共有される画像。 データURIはドキュメントごとのものです。同じ画像がサイトのすべてのページに表示される場合、各ページのHTMLに再埋め込まれ、帯域幅を無駄にします。代わりにキャッシュヘッダー付きの外部URLを使用してください。
オンライン手法のステップバイステップ
画像をオンラインでBase64に変換するのは、1回限りの変換が必要な場合の最も迅速な方法です。
-
画像ファイルを準備します。最良の結果を得るには、まず画像を最適化します。使用する寸法にリサイズし、圧縮し、適切な形式(グラフィックはPNG、写真はJPEG、モダンブラウザにはWebP)を選択します。
-
Base64エンコーディングツールを開きます。Base64エンコーダーデコーダーツールを使用します。ファイルピッカーまたはドラッグ&ドロップによる画像アップロードに対応しています。
-
ツールに画像ファイルをアップロードまたはドラッグします。ツールがファイルを読み取り、即座にBase64に変換します。
-
結果のデータURIをコピーします。出力には
data:image/[format];base64,プレフィックスが含まれているため、HTMLやCSSに直接貼り付けることができます。 -
コードでデータURIを使用します:
- HTML:
<img src="data:image/png;base64,..." alt="description"> - CSS:
background-image: url('data:image/png;base64,...');
- HTML:
JavaScript(ブラウザ)
ブラウザで画像をBase64に変換することは、サーバーにアップロードする前や、画像データをローカルで処理するWebアプリケーションを構築する際など、クライアント側の画像処理に便利です。
function toBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
});
}
// 使用法
document.getElementById('file-input').addEventListener('change', async (e) => {
const file = e.target.files[0];
const base64 = await toBase64(file);
console.log(base64);
});
FileReader.readAsDataURL() メソッドはファイル全体をメモリに読み取り、データURIを生成します。このメソッドは非同期であるため、メインスレッドをブロックしません。非常に大きなファイル(100 MB以上)の場合は、メモリ問題を避けるためにファイルをチャンクでストリーミングすることを検討してください。
Node.js
Node.jsサーバー環境では、データベースへの保存、APIレスポンスでの送信、生成されたHTMLドキュメントへの埋め込みの前に、画像をBase64に変換する場合があります。
const fs = require('fs');
const path = require('path');
const imagePath = path.join(__dirname, 'image.png');
const image = fs.readFileSync(imagePath);
const base64 = image.toString('base64');
const dataUri = `data:image/png;base64,${base64}`;
大きなファイルの場合は、イベントループをブロックしないように非同期 fs.readFile() を使用してください。image.toString('base64') の呼び出しはBufferをBase64文字列に変換します。ファイル拡張子を調べるか、mime-types のようなライブラリを使用して正しいMIMEタイプを判断できます。
Python
Pythonの base64 モジュールを使用すると、画像からBase64への変換が簡単に行えます。このアプローチは、DjangoやFlaskなどのWebフレームワークでテンプレート内のデータURIを生成するために一般的に使用されます。
import base64
with open('image.png', 'rb') as f:
base64_str = base64.b64encode(f.read()).decode('utf-8')
data_uri = f'data:image/png;base64,{base64_str}'
'rb' モードはファイルをバイナリモードで開きます。これは画像データの読み取りに必要です。base64.b64encode() 関数はバイトを返すため、.decode('utf-8') を呼び出してデータURIに含める文字列に変換します。
Python(MIMEタイプ検出付き)
import base64
import mimetypes
def image_to_data_uri(image_path):
mime_type, _ = mimetypes.guess_type(image_path)
if not mime_type:
raise ValueError(f'Could not determine MIME type for {image_path}')
with open(image_path, 'rb') as f:
base64_str = base64.b64encode(f.read()).decode('utf-8')
return f'data:{mime_type};base64,{base64_str}'
この拡張バージョンは、ファイル拡張子に基づいてMIMEタイプを自動的に検出するため、手動でタイプを指定せずに複数の画像形式を処理するのに適しています。
PHP
PHPはサーバー側Webアプリケーションで一般的に使用され、組み込みのBase64エンコーディング関数を提供します。
$image = file_get_contents('image.png');
$base64 = base64_encode($image);
$dataUri = 'data:image/png;base64,' . $base64;
大きなファイルの場合、PHPのメモリ制限が file_get_contents() によって超過される可能性があります。数メガバイトを超えるファイルには、ストリーミングでの fopen() を使用してください。finfo 拡張機能を使用してMIMEタイプを自動検出することもできます:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, 'image.png');
finfo_close($finfo);
$image = file_get_contents('image.png');
$base64 = base64_encode($image);
$dataUri = 'data:' . $mimeType . ';base64,' . $base64;
パフォーマンスに関する考慮事項
Base64画像を使用する場合は、以下のパフォーマンスのトレードオフを考慮してください。
HTMLサイズの増加。 Base64エンコードされた画像はHTMLファイルサイズを増加させ、初期ページレンダリングを遅らせます。小さな画像の場合、これはHTTPリクエストの削減によって相殺されます。大きな画像の場合、この遅延は許容できません。
CPUオーバーヘッド。 ブラウザはレンダリング前にBase64をバイナリにデコードする必要があります。このデコードにはCPU時間がかかりますが、最新のブラウザは毎秒数百メガバイトでBase64をデコードするため、小さな画像ではこのオーバーヘッドは無視できます。
キャッシュの粒度のなさ。 データURIはHTMLまたはCSSファイルの一部としてキャッシュされます。単一の画像を更新すると、含まれているファイル全体のキャッシュが無効になります。外部画像の場合、変更された画像ファイルのみを再フェッチする必要があります。
Gzip圧縮。 Base64エンコードデータは、生のバイナリと比較してgzipで圧縮率が低くなります。これは、Base64がバイトストリームにより多くのエントロピーを生成する限られたアルファベットを使用するためです。ただし、Base64画像を含むページのgzip圧縮サイズ全体は、各画像の個別のHTTPリクエストのネットワークオーバーヘッドよりも依然として小さいことがよくあります。