使用Firebase 3.0.x版本,能否将Base64编码的图像保存到新的Firebase Storage服务中?
我在浏览器中使用canvas对上传前的图片进行调整大小,并将其输出为Base64 JPEG格式。我知道Storage API可以接受Blobs,但我的当前项目需要支持IE9。
使用Firebase 3.0.x版本,能否将Base64编码的图像保存到新的Firebase Storage服务中?
我在浏览器中使用canvas对上传前的图片进行调整大小,并将其输出为Base64 JPEG格式。我知道Storage API可以接受Blobs,但我的当前项目需要支持IE9。
您只需使用putString函数,而无需将BASE64转换为blob。
firebase.storage().ref('/your/path/here').child('file_name')
.putString(your_base64_image, ‘base64’, {contentType:’image/jpg’});
确保在使用函数putString时,将元数据{contentType: 'image/jpg'} 作为第三个参数传递(可选),以便您以图像格式检索数据。
或者简单来说:
uploadTask = firebase.storage().ref('/your/path/here').child('file_name').putString(image, 'base64', {contentType:'image/jpg'});
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, // or 'state_changed'
function(snapshot) {
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
switch (snapshot.state) {
case firebase.storage.TaskState.PAUSED: // or 'paused'
console.log('Upload is paused');
break;
case firebase.storage.TaskState.RUNNING: // or 'running'
console.log('Upload is running');
break;
}
}, function(error) {
console.log(error);
}, function() {
// Upload completed successfully, now we can get the download URL
var downloadURL = uploadTask.snapshot.downloadURL;
});
你可以使用downloadURL来保存到firebase.database(),或将其作为<img>
标记的src。最新版本的Firebase SDK支持base64图片上传。只需使用Firebase Storage中的putString
方法即可。
https://firebase.google.com/docs/reference/js/firebase.storage
需要注意的是,有时候你会遇到带有不必要空格的base64字符串。例如,我发现cordova相机插件返回的base64带有不必要的空格。由于JavaScript无法执行其本地atob
函数(Firebase JS在其底层进行了处理),因此Storage SDK将无法上传此类字符串。您需要去除空格 - 参见DOM Exception 5 INVALID CHARACTER error on valid base64 image string in javascript
是的,现在是可能的。你应该使用Firebase Storage的新方法putString
。你可以在这里阅读规范here。
因此,Firebase规范表示,现在有两种方法可以存储Base64字符串和Base64url字符串:
// Base64 formatted string
var message = '5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
ref.putString(message, 'base64').then(function(snapshot) {
console.log('Uploaded a base64 string!');
});
// Base64url formatted string
var message = '5b6p5Y-344GX44G-44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
ref.putString(message, 'base64url').then(function(snapshot) {
console.log('Uploaded a base64url string!');
})
根据我的经验,在使用putString(message, 'base64url')
时,会不断返回关于Base64字符串代码格式不正确的错误,错误信息为"storage/invalid-format", message: "Firebase Storage: String does not match format 'base64': Invalid character found"。解决方法是去掉字符串开头的data:image/jpeg;base64,
,并改用第一种方法putString(message, 'base64')
。这样就可以正常工作了。
canvas.toBlob()
,您将获得需要传递到Firebase Storage的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);
});
});
};
atob()
。import { getStorage, ref, uploadString } from "firebase/storage";
const storage = getStorage();
const storageRef = ref(storage, 'some-child');
// Data URL string
const message4 = 'data:text/plain;base64,5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
uploadString(storageRef, message4, 'data_url').then((snapshot) => {
console.log('Uploaded a data_url string!');
});
.toBlob()
,虽然它的性能较低,但它可以完成工作。(例如:image/png)
和一个回调函数,用于在使用atob()
构建blob时触发。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;
};
$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,请参考此polyfill:https://github.com/eligrey/Blob.js/blob/master/Blob.js
使用Google Cloud Storage API,这个解决方案适用于我。
但是,通过使用 ref put 方法替换 file.save,它也应该适用于 Firebase。
const file = storage.file(file_path_in_gs)
const contents = new Uint8Array(Buffer.from(base64ImgStr, 'base64'))
file.save(contents,
{
contentType: img_type,
metadata: {
metadata: {
contentType: img_type,
firebaseStorageDownloadTokens: uuid()
}
}
}
, () => { })
const contents = new Uint8Array(Buffer.from(base64ImgStr, 'base64'))
这一行非常重要。我之前尝试将 contents=base64ImgStr
,但是没有成功。 - Wilfred Almeida