firebase 3.0.x を使用して、base64 でエンコードされた画像を新しい Firebase Storage サービスに保存できますか?
キャンバスを使用して、アップロードする前にブラウザで画像のサイズを変更し、base64 jpeg として出力しています。ストレージ API が BLOB を受け入れることができることはわかっていますが、現在のプロジェクトには IE9 のサポートが必要です。
firebase 3.0.x を使用して、base64 でエンコードされた画像を新しい Firebase Storage サービスに保存できますか?
キャンバスを使用して、アップロードする前にブラウザで画像のサイズを変更し、base64 jpeg として出力しています。ストレージ API が BLOB を受け入れることができることはわかっていますが、現在のプロジェクトには IE9 のサポートが必要です。
Firebase SDK の最新バージョンは、base64 画像のアップロードをサポートしています。putString
Firebase Storageのメソッドを使用するだけです。
https://firebase.google.com/docs/reference/js/firebase.storage
1 つの小さな注意点は、base64 文字列に不要な空白が含まれている場合があることです。たとえば、cordova Camera プラグインが base64 を不要な空白で返すことがわかりました。JavaScript はネイティブ機能を実行できないため、ストレージ SDK はこれをアップロードできません。これatob
は、Firebase JS が内部で行うことです。空白を削除する必要があります - DOM Exception 5 INVALID CHARACTER error on valid base64 image string in javascriptを参照してください
を使用すると、Firebase Storage に渡す必要がある をcanvas.toBlob()
取得できます。byte[]
簡単な例:
function save() {
var canvas = document.getElementById("canvas");
canvas.toBlob(blob => {
var storage = firebase.app().storage().ref();
var name = id + "/" + (new Date()).getTime() + ".png";
var f = storage.child("drawings/" + name);
var task = f.put(blob);
task.on('state_changed', function(snapshot) {
}, function(error) {
console.error("Unable to save image.");
console.error(error);
}, function() {
var url = task.snapshot.downloadURL;
console.log("Saved to " + url);
var db = firebase.database();
var chats = db.ref().child("chats");
chats.child(id).child("drawingURL").set(url);
});
});
};
それ以外の場合は、base64 を自分で変換する必要があります。たとえば、atob()
.
ここでは、サポートを支援するために使用する 2 つの値を示しますが.toBlob()
、パフォーマンスは低下しますが、仕事は完了します。
このメソッドは、base64 文字列、コンテンツ タイプ(IE: image/png)
、および blob が次を使用して構築されたときのコールバックを受け取ります。atob()
var b64_to_blob = function(b64_data, content_type, callback) {
content_type = content_type || '';
var slice_size = 512;
var byte_characters = atob(b64_data);
var byte_arrays = [];
for(var offset = 0; offset < byte_characters.length; offset += slice_size) {
var slice = byte_characters.slice(offset, offset + slice_size);
var byte_numbers = new Array(slice.length);
for(var i = 0; i < slice.length; i++) {
byte_numbers[i] = slice.charCodeAt(i);
}
var byte_array = new Uint8Array(byte_numbers);
byte_arrays.push(byte_array);
}
var blob = new Blob(byte_arrays, {type: content_type});
callback(blob);
};
私はこのメソッドを使用して、必要に応じてダイレクト リンクの base64 値を取得します。私の場合は、ユーザーがアプリケーションに登録するときに、ユーザーの Facebook の写真をダウンロードします。
var image_link_to_b64 = function(url, content_type, callback) {
var image = new Image();
image.crossOrigin = 'Anonymous';
image.onload = function() {
var canvas = document.createElement('CANVAS');
var context = canvas.getContext('2d');
var data_url;
canvas.height = this.height;
canvas.width = this.width;
context.drawImage(this, 0, 0);
data_url = canvas.toDataURL(content_type);
data_url = data_url.substr(22);
callback(data_url);
canvas = null;
};
image.src = url;
};
以下は、firebase storage に情報を追加したときの様子です。
$fileService.image_link_to_b64(facebook_info.photoURL + '?width=512&height=512', 'image/png', function(b64) {
$fileService.b64_to_blob(b64, 'image/png', function(blob) {
$fileService.upload_user_photo(blob, 'image/png', function(url) {
// Firebase storage download url here
}
}
}
ご想像のとおり、upload_user_photo は単純に firebase ストレージにアップロードします。
var upload_user_photo = function(data, blob, callback) {
var upload_task = user_photo_reference.child('user_photo').put(data);
upload_task.on('state_changed', function(snapshot) {
}, function(error) {
alert('error: ', error);
}, function() {
callback(upload_task.snapshot.downloadURL);
});
};]
IE9 については、次のポリフィルを参照してください: https://github.com/eligrey/Blob.js/blob/master/Blob.js