Как я могу преобразовать двоичный файл изображения из вызова API в URI данных в Javascript? - PullRequest
7 голосов
/ 06 декабря 2011

API Google, который я использую, передает изображения только в виде двоичных данных.

Я совершенно не представляю, как поместить это в URI данных для его отображения, спасибо за любую помощь!

Вызов, о котором я говорю, это этот вызов API .

Как видите, он говорит:

Сервер возвращаетбайт фотографии.

Для вызова (это расширение) я использую методы chrome_ex_oauth.Может быть, мне нужно добавить что-то в заголовок, чтобы получить реальные двоичные данные, а не строки, как это происходит прямо сейчас ...

Что мне нужно сделать, это преобразовать полученный двоичный файл в URI данных, чтобы я мог отобразитьэто.


Хорошо, я получаю это из XHR-запроса

enter image description here

Теперь я не очень разбираюсь в бинарных вещах.Это как-то закодированные двоичные данные я предполагаю?Я пытался поместить это в btoa и другие base64 кодировщики, все выдает ошибку.Я пытался переопределить MimeType разными вещами, и «ответ» изменился каким-то странным образом, но ничто не принимает данные.

Так что теперь у меня есть этот код:

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');

У кого-нибудь еще есть любойИдея, как получить это для меня не понятный ответ в данных URI ???

Спасибо за любую помощь

Ответы [ 4 ]

16 голосов
/ 19 декабря 2011

После проведения некоторых тестов вот мой ответ:

Чтобы просто отобразить изображение с помощью тега <img>, вы должны сначала закодировать двоичный файл результата с помощью Base64.Это можно сделать двумя разными способами:

  1. Использование Javascript: Использовать функцию кодера Base64, , например, эту .После того, как вы закодировали результирующие двоичные данные, вы можете отобразить изображение с помощью тега <img> следующим образом: <img src="data:image/*;base64,[BASE64 ENCODED BINARY]" />.Вы должны заменить [BASE64 ENCODED BINARY] фактическим закодированным двоичным файлом изображения.Я предполагаю, что вы уже знаете, как изменить атрибуты HTML-элемента с помощью Javascript, довольно просто поместить закодированный двоичный файл в атрибут src тега <img>.

  2. Использование PHP (мои личные предпочтения) : Как только вы отправите запрос GET в API, он вернет вам двоичный файл.Просто используйте функцию PHP base64_encode().

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

Где переменная $result - это то, что вы получаете из вызова API.Вы можете использовать библиотеку PHP cURL .

Надеюсь, это поможет.

5 голосов
/ 20 декабря 2011

Хорошо, я нашел решение ...

Прежде всего, запрос должен переопределить тип returend на x-user-машинный

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

После этого данные не затрагиваютсяв браузере.

Используйте следующий кодировщик 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;
            }
        };

Существует волшебная статья, опубликованная mozilla, которая не позволила мне правильно ее кодировать

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

Финалтогда код будет выглядеть следующим образом ...

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 Если вы вставите «data: image / *» непосредственно в окно браузера, он загрузит файл и не сможет открыть его.Но если вы поместите его непосредственно в img src, он будет работать нормально!

2 голосов
/ 19 декабря 2011

Если вы используете data: URI, я так понимаю, что вам не нужны старые браузеры. В этом случае используйте btoa(), как предложено в Как можно кодировать строку в Base64 в JavaScript? и использовать альтернативу, упомянутую во втором ответе . Тогда data: URI прост:

data:image/*;base64,<the btoa output>
1 голос
/ 31 марта 2013

Все остальные решения устарели.Нет Base64 не требуется.Проверьте мой ответ на Получение BLOB-данных из XHR-запроса .

...