javascript - 如何在存储在数据库中的 vue.js 中呈现 blob 图像

标签 javascript postgresql vue.js blob sequelize.js

我在前端使用 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 访问的对象是 Buffer 类型的对象。

Console shows this is an Object with type 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 借自here :

    imgUrl(){
      const objUrl = window.URL.createObjectURL(new Blob(this.item.image.data));

      return objUrl;
    }

创建一个从 here 借来的 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(借用 here ):

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 模型定义一个 getter

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

}

关于javascript - 如何在存储在数据库中的 vue.js 中呈现 blob 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50157926/

相关文章:

database - Odoo 数据库登录问题?

vue.js - Vue 3 Teleport 是否只能移植到 vue 之外?

javascript - 单击项目后关闭抽屉导航?

javascript - 将表单数据发送到邮件时的 Bootstrap 弹出窗口

javascript - 无法运行 node.js 服务器以使用 express 和 multer 在 Node 中上传文件

MySQL 从外部集中选择不在表中的值

performance - 在大数据集上使用v-model时如何让vuejs响应更快

javascript图形库

javascript - knockoutjs 和同位素添加新项目导致第一个元素跳来跳去

ruby-on-rails - ActiveRecord 错误的表名