【问题标题】:How store image binary directly to db (no GridFS)如何将图像二进制文件直接存储到数据库(无 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;
        })
    }
})

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

【问题讨论】:

    标签: meteor


    【解决方案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 见stackoverflow.com/questions/12710001/… 这是更多的工作
    • 感谢@Green,我现在用&lt;img src="{{this.binary}}"&gt; 显示图像。不确定我是否理解 getElementById 方法——但我是 JS 新手——我猜我必须做一些功课。无论如何,我很好奇您对将这个概念用于小型图像数据库有何看法——或者无论如何我应该使用 CollectionFS?
    • 对于小数字,可能没问题。我在这里写了一些利弊stackoverflow.com/questions/27934141/…
    【解决方案2】:

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

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

    这是相同的参考-

    How to convert an image to base64 in JavaScript

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-25
      • 2012-05-16
      相关资源
      最近更新 更多