Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tantaman/6921973 to your computer and use it in GitHub Desktop.
Save tantaman/6921973 to your computer and use it in GitHub Desktop.
Download an image, save it to IndexedDB, read it out, display the image via createObjectURL - works in Chrome and Firefox. Based on https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/ but with fixes made for Chrome.
(function () {
// IndexedDB
function BrowserType() {
var n = navigator.appName;
var ua = navigator.userAgent;
var tem;
var m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
if (m && (tem = ua.match(/version\/([\.\d]+)/i)) != null) m[2] = tem[1];
m = m ? [m[1], m[2]] : [n, navigator.appVersion, '-?'];
if ((m[0] == "Netscape") && ua.match(/rv:11/g)) {
m[0] = "MSIE";
}
return { brand: m[0], version: m[1] };
}
var browserName = BrowserType().brand;
console.log(browserName);
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
dbVersion = 1.0;
// Create/open database
var request = indexedDB.open("elephantFiles", dbVersion),
db,
createObjectStore = function (dataBase) {
// Create an objectStore
console.log("Creating objectStore")
dataBase.createObjectStore("elephants");
},
getImageFile = function () {
// Create XHR
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", "elephant.jpg", true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
// Blob as response
blob = xhr.response;
console.log("Blob:" + blob);
// Put the received blob into IndexedDB
putElephantInDb(blob);
}
}, false);
// Send XHR
xhr.send();
},
convertToBase64 = function(blob, cb) {
var fr = new FileReader();
fr.onload = function(e) {
cb(e.target.result);
}
fr.readAsDataURL(blob);
},
dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = parts[1];
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType});
},
putElephantInDb = function (blob) {
console.log("Putting elephants in IndexedDB");
// Put the blob into the dabase
if (browserName == 'Chrome') {
// Chrome can't store blobs at the moment.
// Convert to base64.
convertToBase64(blob, continuation);
} else {
continuation(blob);
}
function continuation(blob) {
// Open a transaction to the database
var transaction = db.transaction(["elephants"], 'readwrite');
var put = transaction.objectStore("elephants").put(blob, "image");
// Retrieve the file that was just stored
transaction.objectStore("elephants").get("image").onsuccess = function (event) {
var imgFile = event.target.result;
console.log("Got elephant! " + imgFile);
// we've received our image from the database. Convert it back to
// a blob if it is not a blob already.
if (browserName == 'Chrome') {
// Why conver to a blob instead of using the data url?
// because data URLs are huge and contain the entire image int he url.
// If you reference the same image multiple times
// with a data url you essentially
// end up with multiple copies of your image floating around.
// dataUrls also take up JS heap space.
imgFile = dataURLToBlob(imgFile);
}
// Get window.URL object
var URL = window.URL || window.webkitURL;
// Create and revoke ObjectURL
var imgURL = URL.createObjectURL(imgFile);
// Set img src to ObjectURL
var imgElephant = document.getElementById("elephant");
imgElephant.setAttribute("src", imgURL);
// localStorage.setItem('img', imgURL);
// window.open('blank.html');
// Revoking ObjectURL
URL.revokeObjectURL(imgURL);
};
}
};
request.onerror = function (event) {
console.log("Error creating/accessing IndexedDB database");
};
request.onsuccess = function (event) {
console.log("Success creating/accessing IndexedDB database");
db = request.result;
db.onerror = function (event) {
console.log("Error creating/accessing IndexedDB database");
};
// Interim solution for Google Chrome to create an objectStore. Will be deprecated
if (db.setVersion) {
if (db.version != dbVersion) {
var setVersion = db.setVersion(dbVersion);
setVersion.onsuccess = function () {
createObjectStore(db);
getImageFile();
};
}
else {
getImageFile();
}
}
else {
getImageFile();
}
}
// For future use. Currently only in latest Firefox versions
request.onupgradeneeded = function (event) {
createObjectStore(event.target.result);
};
})();
@joyjitpal100
Copy link

i am getting an error in the same code for chrome
failed to execute transaction on IDBDatabase:one of the specified object stores were not found

@ananyaojha
Copy link

I'm getting this error. Please helpp.
Uncaught ReadOnlyError: Failed to execute 'put' on 'IDBObjectStore': The transaction is read-only.

@juristr
Copy link

juristr commented May 8, 2018

// Chrome can't store blobs at the moment.

Is this still up to date?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment