PHPで画像投稿を行うフォームを実装した際に、投稿前の確認画面で選択した画像ファイルを表示したい場面があったのでbase64エンコードとData URIを使って表示してみました。
この記事ではPHP 7.3.7を使用しています。
目的
- 投稿前にアップする画像のプレビューを表示し、完了画面でサーバに保存させたい。
- 要するに画像を保存する前に表示させたい。
メリット
- あくまでサーバ上のテンポラリファイルを表示しているだけなので、このままブラウザを閉じてもサーバ上に画像ファイルは残らない。
- HTMLコードに画像をインラインイメージで埋め込むことにより、HTTPリクエストを減らすことが可能になる。
デメリット
- HTMLコードに埋め込む形となるため、画像サイズに伴ってHTMLコードのサイズが大きくなる。
解説
1.file_get_contentsを使ってファイルの内容を全て文字列にして読み込みます。
$img = file_get_contents($_FILES['file']['tmp_name']);
2.base64でエンコードします。
$base64 = base64_encode($img);
3.MIMEタイプも表示時に必要になるため、mime_content_typeを使って取得しておきます。
$mime_type = mime_content_type($_FILES['file']['tmp_name']);
4.後はHTML側にエンコードした画像データとMIMEタイプを渡し、DataURIスキームを使用して表示してもらいます。
<img src="data:(MIMEタイプ);base64,(エンコードした画像データ)" />
上記手順を纏めると下記のようになります。
これで画像が表示されます。
以下は実際にSmartyを使ってHTML側に画像を渡す際の実装例です。
php側
if(is_uploaded_file($_FILES['file']['tmp_name'])){
// MIMEタイプを取得
$mime_type = mime_content_type($_FILES['file']['tmp_name']);
// ファイル内容をbase64でエンコード
$img = file_get_contents($_FILES['file']['tmp_name']);
$base64 = base64_encode($img);
// HTML側に渡す
$smarty->assign('mime_type', $mime_type);
$smarty->assign('up_img', $base64);
}
html側
<img src="data:{$mime_type};base64,{$up_img}" />
参考資料
実装を行う際にこちらの記事を参考にさせていただきました。
表示速度改善 Data URIスキーム - 仕組みとメリット | CodeGrid
Data URIとBase64の基本を理解する
PHPで画像をbase64エンコードしてインラインイメージとしてimgタグで表示する方法