javascript - 如何在存储在数据库中的 vue.js 中呈现 blob 图像
问题描述
我在前端使用 Vue.js。我在后端有 Node.js、Express、PostgreSQL(带有Sequelize)。
我在数据库中存储了一个包含缩略图的项目。
数据库模型
const Item = sequelize.define('item', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.TEXT,
allowNull: false,
},
image: {
type: Sequelize.BLOB('long'),
allowNull: true,
},
就数据库而言,图像被存储为 Blob,我认为这很好(是的,我知道将图像放入数据库不是最佳实践)。
我在浏览器中观察到,我在 Vue 模板中访问this.item.image
的对象是一个 Object 类型Buffer
。
添加到数据库
我在我的 vue 模板中将项目添加到浏览器中的数据库中:
<label for="image" class="itemCreate__field itemCreate__field--image">
<span class="itemCreate__fieldLabel">Image</span>
<input id="file" type="file" accept="image/*" @change="onFileChange"/>
<img v-if="itemPreviewImage" :src="itemPreviewImage" />
</label>
该 HTML 依赖于这些方法:
onFileChange(evt) {
const files = evt.target.files || evt.dataTransfer.files;
if (!files.length) return;
this.createImage(files[0]);
},
createImage(file) {
const image = new Image();
const reader = new FileReader();
reader.onload = evt => {
this.itemPreviewImage = evt.target.result;
this.item.image = evt.target.result;
}
reader.readAsDataURL(file);
},
我在渲染图像的 vue 模板中有这个:
<div v-if="item.image">
<img :src="imgUrl" alt="Picture of item"/>
</div>
从数据库渲染
我尝试了以下方法,但不起作用:
createObjectUrl
从这里借来的:
imgUrl(){
const objUrl = window.URL.createObjectURL(new Blob(this.item.image.data));
return objUrl;
}
创建从这里借来的 base64 字符串:
imgUrl(){
const intArray = new Uint8Array(this.item.image.data);
const reducedArray = intArray.reduce((data, byte) => data + String.fromCharCode(byte), '');
const base64String = `data:image/png;base64, ${btoa(reducedArray)}`;
return base64String;
}
创建一个新Uint8Array
的然后获取一个 objectUrl(在此处借用):
imgUrl(){
const arrayBuffer = new Uint8Array(this.item.image);
const blob = new Blob([arrayBuffer], {type: "image/png"});
return window.URL.createObjectURL(blob);
}
在所有情况下(包括一些使用 FileReader 的尝试),我都会得到损坏的图像。不过,我没有在控制台中收到错误。
我认为问题在于我没有向数据库提交正确的数据。
我正在发送一个将文件附加为属性的 Ajax 请求,我可能应该将其转换为 ¿ 其他东西?
解决方案
首先,确保你得到一个有效的base64
字符串:https ://codebeautify.org/base64-to-image-converter
然后尝试为Item
模型定义一个吸气剂
const Item = sequelize.define('item', {
...
image: {
type: Sequelize.BLOB('long'),
allowNull: true,
get () { // define a getter
const data = this.getDataValue('image')
return data ? data.toString('base64') : ''
},
set(val) {
this.setDataValue('image', val);
}
},
...
}
计算属性
imgURL () {
return this.item.image
? 'data:image/png;charset=utf-8;base64,' + this.item.image
: '' // some default image
}
推荐阅读
- c++ - 在linux c ++中没有通过串口发送数据
- python - 全局变量不会从线程内的异步循环内更新
- mongodb - Mongoose 更新未更新:{ ok: 0, n: 0, nModified: 0 }
- hadoop - Hive 2.1.1 版本是否支持重命名数据库?
- ios - Swift - 如果在其外部触摸则隐藏视图
- r - 用 r 解码散列
- c - 在ARM中添加数组指针
- c# - Visual Studio 正在尝试从与 .csproj.user 中指定的路径不同的路径运行应用程序
- javascript - 用于追求最大值的 Javascript
- jquery - Html:根据第一个选择器过滤第二个选择器