简体   繁体   English

如何将图像二进制文件从 API 调用转换为 Javascript 中的数据 URI?

[英]How can I convert image binary from API call to data URI in Javascript?

The Google API I'm using is transmitting images only as binary data.我使用的 Google API 仅将图像作为二进制数据传输。

I have absolutly no idea how to put this into a data URI to display it, thanks for any help!我完全不知道如何将其放入数据 URI 中以显示它,感谢您的帮助!

The call I'm talking about is this API call .我正在谈论的调用是这个 API 调用

As you can see, it says:如您所见,它说:

The server returns bytes of the photo.服务器返回照片的字节数。

For the call (it's an extension), I use the chrome_ex_oauth methods.对于呼叫(它是一个扩展),我使用 chrome_ex_oauth 方法。 Maybe I need to add something into the header to get real binary data, not string as it comes in right now...也许我需要在标题中添加一些东西来获取真正的二进制数据,而不是现在出现的字符串......

What I need to do is to convert the resulting binary into data URI so I can display it.我需要做的是将生成的二进制文件转换为数据 URI,以便我可以显示它。


Ok, I get this out of the XHR request好的,我从 XHR 请求中得到了这个

在此处输入图片说明

Now, I dont know binary stuff much.现在,我不太了解二进制的东西。 This is somehow encoded binary data i assume?我假设这是以某种方式编码的二进制数据? I tried to put this into btoa and other base64 encoders, everything throws an error.我试图把它放到 btoa 和其他 base64 编码器中,一切都会引发错误。 I tried to overrideMimeType with different things and the "response" changed in some strange ways, but nothing accepts the data.我试图用不同的东西覆盖 MimeType 并且“响应”以一些奇怪的方式改变,但没有任何东西接受数据。

So now I have this code:所以现在我有这个代码:

var nxhr = new XMLHttpRequest();
nxhr.onreadystatechange = function (data) {
    if (nxhr.readyState == 4) {
        console.log(nxhr);
    }
};
nxhr.open(method, url, true);
nxhr.setRequestHeader('GData-Version', '3.0');
nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
nxhr.send('Data to send');

Anybody else has any idea how to get this for me not understandable response into a data uri???其他任何人都知道如何将这个对我来说无法理解的响应转换为数据 uri???

Thanks for any help谢谢你的帮助

After conducting some tests, here is my answer:经过一些测试,这是我的答案:

To simply display the image using the <img> tag, you must first encode the result binary with Base64.要使用<img>标签简单地显示图像,您必须首先使用 Base64 对结果二进制文件进行编码。 You can do this in two different ways:您可以通过两种不同的方式执行此操作:

  1. Using Javascript: Use a Base64 encoder function, such as this one .使用 Javascript:使用 Base64 编码器函数,例如 this one After you encode the result binary data, you can display the image using the <img> tag like so: <img src="data:image/*;base64,[BASE64 ENCODED BINARY]" /> .在对结果二进制数据进行编码后,您可以使用<img>标记显示图像,如下所示: <img src="data:image/*;base64,[BASE64 ENCODED BINARY]" /> You must replace [BASE64 ENCODED BINARY] with the actual encoded binary of the image.您必须用图像的实际编码二进制替换[BASE64 ENCODED BINARY] I'm assuming you already know how to change HTML element attributes through Javascript, it's fairly easy to put the encoded binary into the src attribute of the <img> tag.我假设您已经知道如何通过 Javascript 更改 HTML 元素属性,将编码的二进制文件放入<img>标记的src属性中是相当容易的。

  2. Using PHP (my personal preference) : Once you submit a GET request to the API, it will return you the binary.使用 PHP(我的个人偏好) :一旦您向 API 提交 GET 请求,它就会返回二进制文件。 Simply use the PHP base64_encode() function.只需使用 PHP base64_encode()函数即可。

    <img src="data:image/*;base64,<?php echo base64_encode($result); ?>" />

Where, the $result variable is what you get from the API call.其中, $result变量是您从 API 调用中获得的。 You can use the PHP cURL library.您可以使用PHP cURL库。

I hope this helps.我希望这有帮助。

Ok I found the solution...好的,我找到了解决方案...

First of all, the request must override the returend Type into x-user-defined首先,请求必须覆盖返回类型为x-user-defined

xhr.overrideMimeType('text\/plain; charset=x-user-defined');

After that the data is untouched by the browser.之后,浏览器不会触及数据。

Use the following Base64 encoder使用以下 Base64 编码器

Base64 = {

            // private property
            _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

            encodeBinary: function (input) {
                var output = "";
                var bytebuffer;
                var encodedCharIndexes = new Array(4);
                var inx = 0;
                var paddingBytes = 0;

                while (inx < input.length) {
                    // Fill byte buffer array
                    bytebuffer = new Array(3);
                    for (jnx = 0; jnx < bytebuffer.length; jnx++)
                        if (inx < input.length)
                            bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; // throw away high-order byte, as documented at: https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
                        else
                            bytebuffer[jnx] = 0;

                    // Get each encoded character, 6 bits at a time
                    // index 1: first 6 bits
                    encodedCharIndexes[0] = bytebuffer[0] >> 2;
                    // index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)
                    encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);
                    // index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)
                    encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);
                    // index 3: forth 6 bits (6 least significant bits from input byte 3)
                    encodedCharIndexes[3] = bytebuffer[2] & 0x3f;

                    // Determine whether padding happened, and adjust accordingly
                    paddingBytes = inx - (input.length - 1);
                    switch (paddingBytes) {
                        case 2:
                            // Set last 2 characters to padding char
                            encodedCharIndexes[3] = 64;
                            encodedCharIndexes[2] = 64;
                            break;
                        case 1:
                            // Set last character to padding char
                            encodedCharIndexes[3] = 64;
                            break;
                        default:
                            break; // No padding - proceed
                    }
                    // Now we will grab each appropriate character out of our keystring
                    // based on our index array and append it to the output string
                    for (jnx = 0; jnx < encodedCharIndexes.length; jnx++)
                        output += this._keyStr.charAt(encodedCharIndexes[jnx]);
                }
                return output;
            }
        };

There is the magic stuff posted by mozilla which didnt let me encode the stuff correctly mozilla 发布了一些神奇的东西,它没有让我正确编码这些东西

bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff

The final code would look then like this...最终的代码看起来像这样......

oauth.authorize(function () {
    var method = "GET", params = {}, url = photo.href;

    var nxhr = new XMLHttpRequest();
    nxhr.onreadystatechange = function (data) {
        if (nxhr.readyState == 4) {
            console.log("<img src='data:image/*;base64," + Base64.encodeBinary(nxhr.response) + "' />");
        }
    };
    nxhr.open(method, url, true);
    nxhr.setRequestHeader('GData-Version', '3.0');
    nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
    nxhr.overrideMimeType('text\/plain; charset=x-user-defined'); 
});

PS If you put the "data:image/*" into the browser window directly, it will download the file and would not be able to open it. PS 如果直接在浏览器窗口中输入“data:image/*”,会下载文件而无法打开。 But if you put it directly into an img src it works fine!但是如果你把它直接放到一个 img src 中,它就可以正常工作!

All the other solutions are obsolete.所有其他解决方案都已过时。 No Base64 is needed.不需要 Base64。 Check out my answer on Getting BLOB data from XHR request .查看我关于从 XHR 请求获取 BLOB 数据的回答

I know this is a very old question, but since this is in reference to images and binary data over XHR, the secret sauce for me is in two important steps:我知道这是一个非常古老的问题,但由于这是参考 XHR 上的图像和二进制数据,对我来说,秘诀在于两个重要步骤:

Step 1: Ensure you use a custom user-defined character set to prevent the browser from altering the content.步骤 1:确保使用自定义的用户定义字符集以防止浏览器更改内容。 eg例如

xhr.overrideMimeType('text\/plain; charset=x-user-defined');

Step 2: Use String.fromCharCode(response.charCodeAt(...) & 0xff) to get past the issue with btoa() not being able to handle binary strings.第 2 步:使用String.fromCharCode(response.charCodeAt(...) & 0xff)解决btoa()无法处理二进制字符串的问题。 This was inspired by the gist @ https://gist.github.com/graylikeme/867848 (and it is currently black magic to me right now).这是受到 gist @ https://gist.github.com/graylikeme/867848 的启发(目前对我来说是黑魔法)。

End Eesult: Here's a simplified version of what that comes out to. End Eesult:这是结果的简化版本。 Note that typically you'd also be doing this because you need to send Authorization headers or something too, but that's not included in this example.请注意,通常您也会这样做,因为您还需要发送 Authorization 标头或其他内容,但这并未包含在本示例中。

<div id="output-el"></div>
<script>
    var xhr = new XMLHttpRequest();
    xhr.addEventListener('readystatechange', function() {
        var outputEl = document.getElementById('xhr-output');

        // Done?
        if (this.readyState === 4) {

            // Make sure this is an image.
            var contentType = this.getResponseHeader('content-type');
            if (contentType !== null && contentType.indexOf('image/') === 0) {
                // Prepare binary response so we can base64 encode it (and btoa() function doesn't freak out).
                // Thanks to: https://gist.github.com/graylikeme/867848
                var response = this.responseText;
                var binary = '';
                for(i=0; i < response.length; i++) {
                    binary += String.fromCharCode(response.charCodeAt(i) & 0xff);
                }

                // Drop into data URI.
                var encoded = btoa(binary);
                outputEl.innerHTML = `<img alt="image preview" src="data:${contentType};base64,${encoded}">`;

            } else {
                console.log('Got a non-image response:', this.responseText);
            }
        }
    });

    // Make sure browser doesn't alter the response before we handle it.
    xhr.overrideMimeType('text\/plain; charset=x-user-defined');
    xhr.open('GET', 'https://example.com/path/to/some/image.jpg');
    xhr.send();
</script>

If you're using a data: URI, I take it you don't care about older browsers.如果您使用的是data: URI,我认为您不关心旧浏览器。 In that case, use btoa() as suggested in How can you encode a string to Base64 in JavaScript?在这种情况下,请按照如何在 JavaScript 中将字符串编码为 Base64 中的建议使用btoa() , and fall back on the alternative mentioned in the second answer . ,并回到第二个答案中提到的替代方案 Then, the data: URI is simple:然后, data: URI 很简单:

data:image/*;base64,<the btoa output>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 JavaScript 中将图像 uri(不是 url)转换为 base 64 - How can I convert image uri (not url) to base 64 in JavaScript 如何在Node.js中将同一图像的二进制图像数据转换为URI? - How to convert binary image data to URI for same image in nodejs? 如何将二进制数据从Outlook Mail API转换为JavaScript中的图像源? - How to convert binary data from Outlook Mail API to image source in JavaScript? 将图像转换为二进制数据。 我能怎么做? - convert image to binary data . How can i do? 如何在JavaScript中将二进制数据和MIME转换为图像 - How to convert binary data and mime to image in javascript 如何在javascript中转换为二进制文件? 我如何有一个递归函数一次从每个调用返回数据? - How do I convert to binary in javascript? How do I have a recursive function return data from each call all at once? 如何在JavaScript ajax调用中从PHP passthru获取二进制数据? - How can I get binary data from PHP passthru in JavaScript ajax call? 如何将 API 调用返回的字符串转换为 javascript 中的正确 HTML? - How can I convert string returned from API call to proper HTML in javascript? 图片Javascript中的数据URI - Data URI from Image Javascript 显示从API调用返回为二进制数据的图像 - Show image returned as binary data from API call
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM