<input type="file">で選択した画像を表示したい
<input type="file">
を使って選択した画像を、ファイルをサーバーにsubmit(アップロード)することなくブラウザ上にJavascriptで表示する方法をまとめます。
ファイルをアップロードする前にブラウザ上で選択された画像が確認できるので、プレビュー表示などに使えます。
File要素の変更イベントで選択されたファイルの情報を取得し、imgタグに表示させるという方法です。素のJavascriptでのサンプルと、jQueryを使ったサンプルの2つを以下に載せておきます。
以下のサンプルは、次のようなファイル選択と表示用のimgタグが用意されており、選択されたファイルを表示するというものです。
<input id="file-sample" type="file">
<img id="file-preview">
Javascriptを使ったのサンプル
Blob URL を使う場合
Blob URL はブラウザ内のローカル環境でのみ有効なURLです。ファイル選択時に選択されたファイルのデータから、Blob URL を生成し、それを imgタグの src に設定すると、画像の表示が可能です。
ローカルでのみ有効なので、このURLはほかの端末上では無効です。ページが破棄されるタイミングで Blob URL も無効になります。
仕組みとしてはファイルのバイナリをJavascriptに読み出して、それを表示しているみたいです。
document.getElementById('file-sample').addEventListener('change', function (e) {
// 1枚だけ表示する
var file = e.target.files[0];
// ファイルのブラウザ上でのURLを取得する
var blobUrl = window.URL.createObjectURL(file);
// img要素に表示
var img = document.getElementById('file-preview');
img.src = blobUrl;
});
ファイルを選択すると、imgタグに以下のようなURLが設定されることが確認できます。
<img id="file-preview" src="blob:null/3b6030df-9676-4480-a629-8a8767e06567">
Data URL (Base64) を使う場合
選択したファイルのバイナリをBase64でエンコードした文字列を取得し、それを imgタグの src に設定する方法もあります。
生のバイナリのサイズより30%ほどデータサイズが大きくなるし、データのエンコードに気持ち時間がかかる印象です。データ自体はエンコードされた文字列がすべてなので、ページが破棄されても再表示できます。
document.getElementById('file-sample').addEventListener('change', function (e) {
// 1枚だけ表示する
var file = e.target.files[0];
// ファイルリーダー作成
var fileReader = new FileReader();
fileReader.onload = function() {
// Data URIを取得
var dataUri = this.result;
// img要素に表示
var img = document.getElementById('file-preview');
img.src = dataUri;
}
// ファイルをData URIとして読み込む
fileReader.readAsDataURL(file);
});
jQuery を使ったサンプル
上記Javascriptでの実装を jQuery で行ったサンプルです。
Blob URL を使う場合
$(function() {
$('#file-sample').on('change', function(e) {
// 1枚だけ表示する
var file = e.target.files[0];
// ファイルのブラウザ上でのURLを取得する
var blobUrl = window.URL.createObjectURL(file);
// img要素に表示
$('#file-preview').attr('src', blobUrl);
});
});
Data URL (Base64) を使う場合
$(function() {
$('#file-sample').on('change', function(e) {
// 1枚だけ表示する
var file = e.target.files[0];
// ファイルリーダー作成
var fileReader = new FileReader();
fileReader.onload = function() {
// Data URIを取得
var dataUri = this.result;
// img要素に表示
$('#file-preview').attr('src', dataUri);
}
// ファイルをData URIとして読み込む
fileReader.readAsDataURL(file);
});
});
複数枚の画像を処理したい場合
複数枚の画像を処理したい場合は、すべてのファイルをループしてよしなにしてください。
その場合、Data URL だと処理が少し重いので、Blob URL にした方がよいかなと思います。
以上。
コメントを書く