我有一张带有 base64 的图片,例如
data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QCcUGhvdG9zaG9w....
如何保存在数据库中?架构中字段的类型应该是什么?缓冲?
最佳答案
简短的答案是存储为 "Binary" ,在 Mongoose 模式中,您可以使用 Buffer
来执行此操作。
更长的形式是演示从原始二进制文件开始并再次返回的往返转换。在大多数实际情况中,Base64 编码/解码不是必要的步骤,仅用于演示:
所以Schema部分很简单,使用Buffer
:
var albumSchema = new Schema({
name: String,
image: Buffer
})
那么我们要做的就是按照流程,将二进制数据放入属性中,然后再次读取出来。
请注意,如果您直接来自带有 MIME 类型的字符串,例如:
data:image/png;base64,long-String
只需使用 JavaScript .split()
并为 base64 字符串本身获取第二个数组索引:
var string = "data:image/png;base64,long-String"
var bindata = new Buffer(string.split(",")[1],"base64");
这是一个包含完整演示的 list :
const async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema,
fs = require('fs');
mongoose.Promise = global.Promise;
mongoose.set('debug',true);
mongoose.connect('mongodb://localhost/test');
var albumSchema = new Schema({
name: String,
image: Buffer
})
const Album = mongoose.model('Albumn', albumSchema);
async.series(
[
(callback) =>
async.each(mongoose.models,(model,callback) =>
model.remove({},callback),callback),
(callback) =>
async.waterfall(
[
(callback) => fs.readFile('./burger.png', callback),
(data,callback) => {
// Convert to Base64 and print out a bit to show it's a string
let base64 = data.toString('base64');
console.log(base64.substr(0,200));
// Feed out string to a buffer and then put it in the database
let burger = new Buffer(base64, 'base64');
Album.create({
"title": "burger",
"image": burger
},callback)
},
// Get from the database
(album,callback) => Album.findOne().exec(callback),
// Show the data record and write out to a new file.
(album, callback) => {
console.log(album);
fs.writeFile('./output.png', album.image, callback)
}
],
callback
)
],
(err) => {
if (err) throw err;
mongoose.disconnect();
}
)
NOTE The example was originally given with asyncJS and older mongoose API, which notably has different connection options as shown in more modern and current API examples. Refer to these instead for testing on current NodeJS LTS releases:
或者使用更现代的语法和 API 用法进行比较:
const fs = require('mz/fs');
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/test';
const opts = { useNewUrlParser: true };
mongoose.Promise = global.Promise;
mongoose.set('debug', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
const albumSchema = new Schema({
name: String,
image: Buffer
});
const Album = mongoose.model('Album', albumSchema);
(async function() {
try {
const conn = await mongoose.connect(uri, opts);
await Promise.all(
Object.entries(conn.models).map(([k, m]) => m.deleteMany())
)
let data = await fs.readFile('./burger.png');
// Convert to Base64 and print out a bit to show it's a string
let base64 = data.toString('base64');
console.log(base64.substr(0,200));
// Feed out string to a buffer and then put it in the database
let burger = new Buffer(base64, 'base64');
await Album.create({ "title": "burger", "image": burger });
// Get from the database
// - for demo, we could have just used the return from the create() instead
let album = Album.findOne();
// Show the data record and write out to a new file.
console.log(album);
await fs.writeFile('./output.png', album.image)
} catch(e) {
console.error(e);
} finally {
mongoose.disconnect()
}
})()
即使使用“plain promises”,这也是首选,或者您仍在使用没有 async/await
支持的 NodeJS。但是你really should not be, considering v6.x reaches end of life in April 2019 :
// comments stripped - refer above
const fs = require('mz/fs');
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/test';
const opts = { useNewUrlParser: true };
mongoose.Promise = global.Promise;
mongoose.set('debug', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
const albumSchema = new Schema({
name: String,
image: Buffer
});
mongoose.connect(uri, opts)
.then(conn =>
Promise.all(
Object.entries(conn.models).map(([k, m]) => m.deleteMany())
)
)
.then(() => fs.readFile('./burger.png'))
.then(data => {
let base64 = data.toString('base64');
console.log(base64.substr(0,200));
let burger = new Buffer(base64, 'base64');
return Album.create({ "title": "burger", "image": burger });
})
.then(() => Album.findOne() )
.then(album => {
console.log(album);
return fs.writeFile('./output.png', album.image)
})
.catch(console.error)
.then(() => mongoose.disconnect());
还有一个 burger.png 可以玩:
Also kudos to How to reduce image size on Stack Overflow which allows the sample image here to not appear as "huge" as it originally was, and yet still download at full size.
https://stackoverflow.com/questions/44869479/
相关文章:
node.js - Node/Express - 保护客户端/服务器之间通信的好方法
mongodb - 使用键值对将 mongo 数组转换为对象
c# - ReadBsonType 只能在 State 为 Type 时调用,不能在 State 为
mongodb - Meteor 1.4.1.1 上副本集的正确 MONGO_URL 设置是什么
node.js - Mongoose 类型错误 : User is not a constructo
json - 使用 Python 从 MongoDB 文档创建 JSON 文件
javascript - 为已登录的用户手动创建 Passport session