我有一个带有base64的图片,例如
<div class="sec-1">
<h2>Introducing 'Keeva' world's smartest assistant.</h2>
<div class="flex-box">
<div>
<p class="sales-copy">Keeva smartphone app helps you organize your work schedule, meetings, project deadlines and much more.</p>
<!-- Download Buttons -->
<img class="download-btns" src="img/playstore-1.png">
<img class="download-btns" src="img/iphone-1.png">
</div>
<!-- Phone 0 image -->
<img class="phone-img" src="img/iphone-cut.png" alt="phone image">
</div>
</div>
如何在数据库中保存?模式中字段的类型应该是什么?缓冲器?
答案 0 :(得分:6)
简短答案存储为"Binary",在mongoose模式中,您可以使用Buffer
来执行此操作。
较长的形式是演示从原始二进制文件开始并再次返回的往返转换。在大多数现实世界中,Base64编码/解码不是必要的步骤,只是用于演示:
因此,架构部分很简单,只需使用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");
这是一个包含完整演示的列表:
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();
}
)
注意该示例最初是使用asyncJS和较旧的mongoose API提供的,它们具有不同的连接选项,如更现代和最新的API示例所示。请参考这些来测试当前的NodeJS LTS版本:
或者使用更现代的语法和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()
}
})()
即使是“普通承诺”,或者您仍然使用没有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 :
同样赞赏How to reduce image size on Stack Overflow,它允许此处的示例图像不像原来那样显示为“巨大”,但仍以全尺寸下载。