indexedDBのデータベースに画像を保存する[HTML5新機能]
HTML5の新機能である「indexedDB」のデータベースに画像を保存する方法です。画像ということで、Canvasや画像のスキャンラインも操作していますので、画像処理をある程度知っている方でないと、少し難しいかも知れないです。
事前準備
このサンプルではPromiseオブジェクトという新機能を使用しています。
Chrome/FireFoxなどは標準で使用可能ですが、IEは未対応ですので、互換性があるMITライセンスの「npo.src.js」(8.7KB)を各自でダウンロードして下さい。
※Promiseの詳細に関してはPromiseを使用して複数のファイルを連続して読み込む[IE対応版]の記事をご覧ください。また、indexedDBオブジェクトはPromiseを使用しなくても動作可能です。
indexedDBの確認方法
indexedDBなどのストレージをブラウザで確認するにはF12キーを押して開発者ツールを起動させます。
Chromeの場合は、Applicationを選択すると表示される「Storage」にIndexedDBがあります。
FireFoxは「ストレージインスペクタ」の「IndexedDB DB」です。
IE/Edgeはわかりません。探せばあるかも知れません。
動作確認
・ Internet Explorer 11(32bit/64bit)
・ Microsoft Edge(32bit)
・ Chrome / FireFoxの最新版
※タブレット、スマートフォンやその他のブラウザは未確認です。
使い方
最初に画像ファイルを読み込みます。次に「indexedDBへ画像を保存する」ボタンを押すと、画像がindexedDBのデータベースに保存されます。
その後、自動的にデータベースから画像を読み取って画像の色を反転させてCanvasに描画します。
サンプルコード
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="npo.src.js"></script> <!-- IEの場合は必要 --> <script> // キャンバス var dst_canvas,dst_ctx; // イメージ var image; // 非同期でファイルを読み込む function getAsynchroFile(file) { return new Promise(function(resolve, reject) { var reader = new FileReader(); reader.onload = function (event) { resolve(new Uint8Array(reader.result)); } reader.onerror = function (event) { reject('ファイルの読み込みに失敗しました'); } reader.readAsArrayBuffer(file); }); } window.onload = function () { dst_canvas = document.getElementById("SrcCanvas"); dst_ctx = dst_canvas.getContext("2d"); image = document.getElementById("img_source"); } function OnClick(){ // IndexedDB関連のオブジェクト var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB; // データベースのバージョン // ※データベースの構造を後から変更する際に数値を増やして使用する var dbVersion = 1; // データベースの生成/読み込み、IDBOpenDBRequestオブジェクトを返す var request = indexedDB.open("petitmonte", dbVersion); // DB接続エラー request.onerror = function (event) { alert("IndexedDB データベースに接続できませんでした。"); }; // DB接続成功 request.onsuccess = function (event) { // IDBDatabase var db = request.result; db.onerror = function (event) { alert("IndexedDB データベース接続後にエラーが発生しました。"); }; // キャンバスの画像データ(RAW)を取得する var width = dst_canvas.width; var height = dst_canvas.height; var src = (dst_ctx.getImageData(0,0,width, height)).data; var stream = new Uint8Array(width * height * 3); var sRow,sCol,dRow,count = 0; for (var y = 0; y < height; y++) { sRow = dRow= (y * width * 4); for (var x = 0;x < width; x++) { sCol = sRow + (x * 4); stream[count++] = src[sCol]; stream[count++] = src[sCol + 1]; stream[count++] = src[sCol + 2]; } } // IDBTransaction(読み書き可能なトランザクションを開く) var transaction = db.transaction(["Imagelst"], "readwrite"); // データベースにRAWデータを上書き登録する var put = transaction.objectStore("Imagelst").put(new Blob([stream]), "raw"); // データベースからRAWデータを取得する transaction.objectStore("Imagelst").get("raw").onsuccess = function (event) { var file = event.target.result; // ファイル(RAWデータ)の読み込み getAsynchroFile(file).then(function(raw){ var width = dst_canvas.width; var height = dst_canvas.height; var imagedata = dst_ctx.createImageData(width, height); var dst = imagedata.data; // わかりやすいように、色を反転させてます。 var sRow,dRow,dCol,count = 0; for (var y = 0; y < height; y++) { sRow = dRow= (y * width * 4); for (var x = 0;x < width; x++) { dCol = sRow + (x * 4); dst[dCol] = 255 - raw[count++]; dst[dCol + 1] = 255 - raw[count++]; dst[dCol + 2] = 255 - raw[count++]; dst[dCol + 3] = 255; } } dst_ctx.putImageData(imagedata,0,0); // 読み込みエラー }).catch(function(err){ alert(err); }); }; } // データベースの新規作成 or アップグレードが必要な場合 request.onupgradeneeded = function (event) { var db = event.target.result; // IDBDatabase // オブジェクトストアの生成 db.createObjectStore("Imagelst"); } } function onDragOver(event){ event.preventDefault(); } function onDrop(event){ onAddFile(event); event.preventDefault(); } // ユーザーによりファイルが追加された function onAddFile(event) { var files; var reader = new FileReader(); if(event.target.files){ files = event.target.files; }else{ files = event.dataTransfer.files; } // ファイルが読み込まれた reader.onload = function (event) { // イメージが読み込まれた image.onload = function (){ dst_canvas.width = image.width; dst_canvas.height = image.height; // キャンバスに画像を描画 dst_ctx.drawImage(image,0,0); }; // イメージが読み込めない image.onerror = function (){ alert('このファイルは読み込めません。'); }; image.src = reader.result; }; if (files[0]){ reader.readAsDataURL(files[0]); document.getElementById("inputfile").value = ''; } } </script> </head> <body ondrop="onDrop(event);" ondragover="onDragOver(event);" style="background:#ddd;"> <input type="file" id="inputfile" accept="image/jpeg,image/png,image/gif,image/bmp,image/x-icon" onchange="onAddFile(event);"> <button onclick="OnClick();">indexedDBへ画像を保存する</button> <img id="img_source" style="display:none;"> <p></p> <canvas id="SrcCanvas"></canvas> </body> </html>
データベースやデータの削除
データベース、データ(レコード)の削除は次のようにします。
// データベースの削除 //indexedDB.deleteDatabase('ここにデータベース名を入力'); // データの削除(1レコード) // transaction.objectStore("Imagelst").delete('レコード名'); // 全てのデータの削除(全レコード) // transaction.objectStore("Imagelst").clear();
リンク
IndexedDB (MDN)
IndexedDB に画像とファイルを格納する