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 に画像とファイルを格納する
関連記事
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









