【问题标题】:Taking an image and converting it into BLOB for MySQL拍摄图像并将其转换为 MySQL 的 BLOB
【发布时间】:2022-01-18 19:43:59
【问题描述】:

我正在尝试制作一个 JavaScript 来获取图像文件并将其转换为 BLOB(先将文件转换为 Base64,然后再转换为 BLOB),我的项目不支持 toBlob() 所以我有找到了不同的转换步骤并将它们放在一起,它们工作到我必须从函数中传递 BLOB 的地步,在该函数中,它为负责与数据库通信的 Mysql 部分代码制作。 (我有充分的工作)。现在我只需要找到一种方法,如何通过一个保存imageforQuery函数结果的变量来连接它们。

到目前为止我的代码是这样的:


  let base64String = "";

  function imageforQuery(imageid) {
          //takes file and converts to Base64
          var file = document.getElementById(imageid).files[0];

          var reader = new FileReader();
          console.log("next");
          imgFileFrontBlob = "";
          reader.onload = function () {
              base64String = reader.result.replace("data:", "")
                  .replace(/^.+,/, "");

              // console.log(base64String);
              base64String = 'data:image/jpeg;base64,'+ base64String;
              console.log(base64String);
              //converts Base64 into BLOB
              var binary = atob(base64String.split(',')[1]);
              console.log(binary);
              var array = [];
              for(var i = 0; i < binary.length; i++) {
                  array.push(binary.charCodeAt(i));
              }
              var imgFileFrontBlob = new Blob([new Uint8Array(array)], {type: 'image/png'});

              console.log(imgFileFrontBlob);
              return imgFileFrontBlob

          }

          reader.readAsDataURL(file);


       };

通过在不同阶段对console.log()return 进行试验,我发现我无法将转换后的BLOB 结果传递出去,因为函数imageforQuery() 只返回reader.readAsDataURL(file); 之后的内容而我没有不知道有什么方法可以得出这个结果。

––––––––––––––我遇到的其他问题––––––––––––––––

好的,感谢 Emiel Zuurbier(谢谢!)在他的解决方案的帮助下,我设法重写了我的代码。然而,尽管它对问题的一部分有所帮助,但它对 JavaScript Blob object 并没有帮助,因为我们发现它与 SQL BLOB 并不完全相同。

现在的问题是,在尝试在 SQL 查询中发送 Blob object 时,这导致只发送纯文本“[Blob object]”。

但我成功地使用 JavaScript 从我的数据库中的 BLOB 字段中提取数据,并将其从存储在应用程序不同部分的 BLOB 中的数据转换为 Base64 图像。代码如下:

var converterEngine = function (input) { 
   // fn BLOB => Binary => Base64 ?
   var uInt8Array = new Uint8Array(input),
      i = uInt8Array.length;
   var biStr = []; //new Array(I);
   while (i--) { biStr[i] = String.fromCharCode(uInt8Array[i]);  }
   var base64 = window.btoa(biStr.join(''));
   return base64;
};

我需要做的只是扭转这一点,理论上,它应该得到我从数据库收到的相同数据。 我的反转代码如下:

// this is the inside bit of code from the first problem that is solved and the 
// typeOfData variable is parsed into the function in imageforQuery() as a second input 
// variable (in other words its not to be of concern)
reader.onload = function () {
          let base64String = reader.result.replace("data:", "").replace(/^.+,/, "");
          base64String = "data:" + typeOfData + ";base64," + base64String;

          var binary = atob(base64String.split(",")[1]);
          // console.log(binary);
          var array = [];
          for (var i = 0; i < binary.length; i++) {
            array.push(binary.charCodeAt(i));
          }
          var ourArray = new Uint8Array(array);
          



          resolve(ourArray);
        };

但是,正如我提到的那样,输出的数据 (ourArray) 实际上与数据库中 BLOB 中的原始文件并不完全相同,因此我的代码无法正常运行,我不知道为什么。我犯了错误的任何想法?

【问题讨论】:

    标签: javascript mysql encoding type-conversion blob


    【解决方案1】:

    Base64 就是简单的 ascii 文本。所以 MySQL 的数据类型 BLOBTEXT 可以工作。即转成Base64后,不用担心“转成blob”;没必要。

    也就是说,您可以简单地将//converts ...return ... 的代码替换为

    return base64String;
    

    【讨论】:

    • 我知道这一点。然而,我使用BLOBs 的理由是,如果我需要手动更改数据库,在 MySQL Workbench 中使用BLOBs 会更容易。
    【解决方案2】:

    您可以包装FileReader 实例并在Promise 内调用。立即返回Promise。在reader.onload 函数中调用resolve() 以退出Promise 并带有值。

    function imageforQuery(imageid) {
      return new Promise(resolve => {
        var file = document.getElementById(imageid).files[0];
        var reader = new FileReader();
      
        reader.onload = function () {
          let base64String = reader.result.replace("data:", "").replace(/^.+,/, "");
          base64String = "data:image/jpeg;base64," + base64String;
    
          var binary = atob(base64String.split(",")[1]);
          var array = [];
          for (var i = 0; i < binary.length; i++) {
            array.push(binary.charCodeAt(i));
          }
    
          var imgFileFrontBlob = new Blob([new Uint8Array(array)], {
            type: "image/png",
          });
      
          resolve(imgFileFrontBlob);
        };
    
        reader.readAsDataURL(file);
      });
    }
    

    这将导致能够使用您的功能,如下所示。 imageforQuery 被调用,返回一个Promise。当 Promise 完成时(意味着 resolve 被调用),then 方法中的函数将运行。

    imageforQuery(imageId).then(imgFileFrontBlob => {
      // Use your blob here.
      saveToDB(imgFileFrontBlob); // Example of how you would use it.
    });
    

    或与async / await 一起使用。

    (async () => {
      function imageforQuery(imageid) {
        ...
      }
    
      // Here we can wait for imageforQuery to finish and save the variable.
      const imgFileFrontBlob = await imageforQuery(imageId);
      saveToDB(imgFileFrontBlob); // Example of how you would use it.
    })()
    

    【讨论】:

    • 我需要能够在 SQL 查询中将 blob 发送到数据库中,但是如果我使用 var imgFileFrontBlob = imageforQuery(imageId),则传递到数据库中的只是一个字符串 [object Promise] 而不是实际的 blob,我可以通过什么方式使用 then 方法?
    • 在第二个代码 sn-p 中,您可以看到如何使用返回的 Promise。我添加了指向有关 Promises 工作原理的文档的链接。
    • 如果我将所有用于将数据发送到 DB 的 MySQL 代码放在 imageforQuery(imageId).then(imgFileFrontBlob =&gt; { 中,它仍然只保存一个字符串“[object Blob]”,其中没有实际数据。
    • 而且我不适合制作saveToDB() 函数,因为我正在转换和发送三个不同的文件,所以我真正需要的是只有那个转换函数,然后我可以调用三个每个文件的时间,每个给我一个变量(其中存储一个 blob),然后我可以将所有这些变量放入负责将信息发送到数据库的主代码中。我写了转换函数,它只是没有传递 blob。这就是我需要的。
    • 我想你误会了。 Blob 是一个 JavaScript 对象。它与 SQL 中的 BLOB 不同。因此,您不能只是将一个复制到另一个。无论您使用什么,都将 blob 对象转换为一个字符串,从而为您提供[object Blob]。但是,您可以使用Blob.text()Blob 的内容作为字符串获取。
    猜你喜欢
    • 1970-01-01
    • 2018-08-05
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2013-03-28
    • 1970-01-01
    相关资源
    最近更新 更多