如何将图像二进制文件直接存储到数据库(无 GridFS)

Posted

技术标签:

【中文标题】如何将图像二进制文件直接存储到数据库(无 GridFS)【英文标题】:How store image binary directly to db (no GridFS) 【发布时间】:2015-03-11 07:11:47 【问题描述】:

如何将图像二进制文件直接上传到数据库?我读到只有较大的文件才需要 GridFS。

我的意见:

<template name="pixUpload">
    <input type="file" name="myFile" class="myPixInput">
</template>

还有模板:

Template.pixUpload.events(
    'change .myPixInput': function(event, template) 
        event.preventDefault();
        var pixBinaryVar = event.target.myFile.value;
        MyPix.insert(
            binary: pixBinaryVar;
        )
    
)

它不起作用,我收到未定义值的错误。为什么?

【问题讨论】:

【参考方案1】:
Template.pixUpload.events(
    'change .myPixInput': function(event, template) 
        event.preventDefault();
        var file = event.target.files[0]; //assuming you have only 1 file
        var reader = new FileReader(); //create a reader according to html5 File API

        reader.onload = function(event)
          var result = reader.result //assign the result, if you console.log(result), you get 
          var buffer = new Uint8Array(result) // convert to binary
          MyPix.insert(binary: buffer);
        

        reader.readAsArrayBuffer(file); //read the file as arraybuffer
        //reader.readAsDataURL(file)

    
)

从 Meteor 1.0 开始,当您在 Meteor.call 或 collection.insert 中发送二进制/缓冲区时,它会从客户端转换为 EJSON,然后当它到达服务器时,它会转换回原始二进制/缓冲区

如果您打开 chrome 控制台并查看 websocket 流量,您会看到 EJSON 二进制字符串,它是 base64 编码的。所以另一种方法是使用 reader.readAsDataURL,这会将您的图像直接转换为 base64,从而避免 Meteor 再次这样做。

reader.onload = function(event)
  MyPix.insert(binary: reader.result);

reader.readAsDataURL(file);

【讨论】:

非常感谢@Green! - 你的代码有效,我开始明白这里发生了什么。如果我是正确的,您推荐使用reader.readAsDataURL 的第二种方法。另外,请问您如何在浏览器中显示[object Uint8Array]?我无法解决这个问题。一般来说,这对于小图像数据库来说是一个好方法吗?我们的大部分文件都是低分辨率的:eBoy 如果您调用 readAsDataUrl,console.log 结果将为您提供“data:image/jpg;base64,xxx...”。然后你可以这样做: var img = document.getElementbyId('someImgId'); img.src = 结果;或者在保存到集合之后,如果您将二进制文件存储为 base64 假设您调用了 MyPix.insert(name:'somePic',binary:result);然后显示图像,调用 var result = MyPix.findOne(name:'somePic').binary 然后分配 img.src = result; 另一方面,如果调用 readAsArrayBuffer() 则转换为 Uint8Array。当您尝试 console.log 数组时,您会得到 [.....] 要将其显示为图片,您需要执行 var result = MyPix.findOne(name:'somePic').binary 然后将其转换结果转换为base64: var result_b = arrayToBase(result) 然后分配 img.src = result_b 见***.com/questions/12710001/… 这是更多的工作 感谢@Green,我现在用&lt;img src="this.binary"&gt; 显示图像。不确定我是否理解 getElementById 方法——但我是 JS 新手——我猜我必须做一些功课。无论如何,我很好奇您对将这个概念用于小型图像数据库有何看法——或者无论如何我应该使用 CollectionFS? 对于小数字,可能没问题。我在这里写了一些利弊***.com/questions/27934141/…【参考方案2】:

对于小图像,您可以选择将图像更改为 base64 并将其存储在数据库中。

这可以通过创建 html 画布并在其中绘制图像并获取 base64 图像来完成-

这是相同的参考-

How to convert an image to base64 in javascript

【讨论】:

以上是关于如何将图像二进制文件直接存储到数据库(无 GridFS)的主要内容,如果未能解决你的问题,请参考以下文章

在 MFC 中从二进制文件加载图像

如何在 Impala 中存储图像文件

如何查询blob类型中存的是啥格式的文件

帮助从 SQL Server 读取二进制图像数据到 PHP

使用无服务器框架上传时文件在 S3 上损坏

将二进制图像从数据库保存到文件夹时出错