如何将响应中的二进制图像解析为base64字符串?

Posted

技术标签:

【中文标题】如何将响应中的二进制图像解析为base64字符串?【英文标题】:How to parse into base64 string the binary image from response? 【发布时间】:2014-05-25 16:25:50 【问题描述】:

我想将请求的图像从我的 REST API 解析为 base64 字符串。

首先...我想,这很容易,只需使用window.btoa() 函数即可。

当我尝试在我的应用程序的此类部分执行此操作时:

.done( function( response, position ) 
    var texture = new Image();
    texture.src = "data:image/png;base64," + window.btoa( response ); 

我遇到了下一个错误:Uncaught InvalidCharacterError: Failed to execute 'btoa' on 'Window': 要编码的字符串包含 Latin1 范围之外的字符。

我在这里读到:javascript atob returning 'String contains an invalid character'

由于newlines in the response 而出现问题,这就是window.btoa() 失败的原因。 任何二进制图像格式当然都会有换行符......但是从上面的链接中,建议是删除/替换这些字符 - 对我来说是一个坏建议,因为如果从二进制图像中删除/替换一些字符,它只会是损坏。

当然,可能的替代方案与 API 设计有关: - 添加一些函数,返回 base64 表示 - 添加一些函数,返回图片的url

如果我不修复它,我会从服务器返回base64表示,但我不喜欢这样的方式。

是否存在某种方法来解决我从响应中处理二进制图像的问题,如上面屏幕截图部分所示,不是吗?

【问题讨论】:

你用的是什么API端? @F***Cook 到底在哪里?我建议在哪里更改 API 以返回 base64/url 或在哪里?如果您仔细阅读了我的内容,我想找到一种不使用它的方法并尝试使用其他方式/技巧。从服务器端进行 base64 响应 - 不是问题,但我希望找到一种方法将其作为二进制图像处理。 啊,好吧。会环顾四周。等一下。 你能发布 api 调用以便我测试吗?或者他们有例子吗?我可能有一个解决方案 @F***Cook API 调用很简单:http://host/api/tile?x=x&y=y&zoom=zoom,然后它只从服务器端返回一个图像。当然,我可以添加一些选项&base64=true | false/api/tile.format?x&y=y&zoom=zoom,其中format = .base64,所以它可以看起来像:/api/tile.base?x&y=y&zoom=zoom,但这是另一回事,问题是关于响应中可能的二进制处理。该服务也在本地主机中...... 【参考方案1】:

Base 64 图像数据适合我

<img src="data:image/png;base64,' + responce + '" />

【讨论】:

无效字符应该会阻止这个。这就是他要问的。 这是为 WebGL 项目准备的,不只是显示为静态图像,还有invalid chars...【参考方案2】:

我猜测在将字符串传递给函数之前在字符串上使用escape,如果没有 API 调用,我无法测试自己。

测试

encodeURI("testñ$☺PNW¢=")

返回

"test%C3%B1$%E2%98%BAPNW%C2%A2="

它只是转义所有字符,它应该转义字符串中的所有非法字符

测试

encodeURI("¶!┼Æê‼_ðÄÄ┘Ì+\+,o▬MBc§yþó÷ö")

返回

"%C2%B6!%E2%94%BC%C3%86%C3%AA%E2%80%BC_%C3%B0%C3%84%C3%84%E2%94%98%C3%8C++,o%E2%96%ACMBc%C2%A7y%C3%BE%C3%B3%C3%B7%C3%B6"

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

【讨论】:

我担心转义会损坏图像,所以在转义某些字符后无法显示,因为正确的图像显示需要一些换行符和二进制字符,但感谢帮助并为我花时间。 我建议获得该功能请求。【参考方案3】:

您遇到的问题是响应被视为 Unicode 字符串。请参阅此处有关 Unicode 字符串的部分:window.btoa

这个post提供了几种解决方案

【讨论】:

响应是二进制格式,而不是文本格式(所以它不可能是我认为的 unicode 字符串),如果你仔细看,我已经抓住了 PNG 图像的二进制内容 @GeloVolro - 我确实看到了。当我使用 btoa 遇到同样的错误时,我做了很多搜索。我不确定 Chrome 是否显示带有引号的对象,但考虑到它正在显示数据让我认为它是一个字符串。由于您使用的是 jQuery,因此您可以使用 jQuery.type(response) 来查看类型。【参考方案4】:

我认为您遇到的部分问题是 jQuery.ajax 确实 not 本身支持可以很好地处理二进制数据的 XHR2 blob/arraybuffer 类型(请参阅 Reading binary files using jQuery.ajax)。

如果您使用带有 xhr.responseType = 'arraybuffer' 的原生 XHR 对象,然后读取响应数组并将其转换为 Base64,您将得到您想要的。

这是一个适合我的解决方案:

// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
function fetchBlob(uri, callback) 
  var xhr = new XMLHttpRequest();
  xhr.open('GET', uri, true);
  xhr.responseType = 'arraybuffer';

  xhr.onload = function(e) 
    if (this.status == 200) 
      var blob = this.response;
      if (callback) 
        callback(blob);
      
    
  ;
  xhr.send();
;

fetchBlob('https://i.imgur.com/uUGeiSFb.jpg', function(blob) 
  // Array buffer to Base64:
  var str = btoa(String.fromCharCode.apply(null, new Uint8Array(blob)));

  console.log(str);
  // Or: '<img src="data:image/jpeg;base64,' + str + '">'
);

https://jsfiddle.net/oy1pk8r3/2/

产生 base64 编码的控制台输出:/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAIBAQIBAQICAgICAgICAw.....

【讨论】:

谢谢,我花了一段时间才意识到这解决了我的问题,因为一个错字,但这对我有用。 这拯救了我的一天【参考方案5】:

而不是使用 _arrayBufferToBase64() 循环遍历 blob, 使用 apply() 进行转换, 它在我的浏览器中速度提高了 30 倍,并且更简洁

// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
function fetchBlob(uri, callback) 
  var xhr = new XMLHttpRequest();
  xhr.open('GET', uri, true);
  xhr.responseType = 'arraybuffer';

  xhr.onload = function(e) 
    if (this.status == 200) 
      var blob = this.response;
      if (callback) 
        callback(blob);
      
    
  ;
  xhr.send();
;

fetchBlob('https://i.imgur.com/uUGeiSFb.jpg', function(blob) 
  var str = String.fromCharCode.apply(null, new Uint8Array(blob));
  console.log(str);
  // the base64 data: image is then
  // '<img src="data:image/jpeg;base64,' + btoa(str) + '" />'	
);

【讨论】:

我已将此纳入上述答案。【参考方案6】:

试试这个效果很好。请尝试一次。 @user2402179

  $.ajax(
    type: 'GET',
    url: baseUrl",
    dataType: 'binary',
    xhr() 
      let myXhr = jQuery.ajaxSettings.xhr();
      myXhr.responseType = 'blob';
      return myXhr;
    ,
    headers: 'Authorization': 'Bearer '+token      
    
).then((response) => 
    // response is a Blob
    return new Promise((resolve, reject) => 
      let reader = new FileReader();
      reader.addEventListener('load', () => 
        $('#theDiv').append('<img src="' +reader.result+ '" />')
        resolve(reader.result);
      , false);
      reader.addEventListener('error', () => 
        reject(reader.error);
      , false);
      reader.readAsDataURL(response);
    );
  );

【讨论】:

以上是关于如何将响应中的二进制图像解析为base64字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何将存储在数据库中的 Base64 字符串集合转换为普通图像存储在本地目录中

如何通过 iOS 6 中的 RESTkit 2.0 将 JSON 中的 base64 图像导入核心数据二进制文件?

DOM Exception 5 INVALID CHARACTER 错误在 javascript 中的有效 base64 图像字符串上

如何将 base64 字符串格式的图像转换为清晰图像缩小器期望的数据类型?

如何将图像转换为 Base64 字符串,并转换回图像,保存到 azure blob

MySQL - Base64 vs BLOB