如何将响应中的二进制图像解析为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 字符串格式的图像转换为清晰图像缩小器期望的数据类型?