2014-04-11 48 views
19

Chcę przeanalizować żądany obraz z mojego interfejsu API REST na łańcuch podstawowy64.Jak analizować w base64 napisać obraz binarny z odpowiedzi?

enter image description here

Po pierwsze ... Myślałem, że to będzie łatwe, wystarczy użyć funkcji window.btoa() na ten cel.

Kiedy próbuję to zrobić w takiej części mojej aplikacji:

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

Mam kolejny błąd: Uncaught InvalidCharacterError: Nie udało się wykonać 'btoa' na 'Okno': Łańcuch do być zakodowane zawiera znaki spoza zakresu Latin1.

Jak czytam tutaj: javascript atob returning 'String contains an invalid character'

Ten problem występuje z powodu newlines in the response i dlatego window.btoa() powiodło się. Każdy format obrazu binarnego oczywiście będzie miał znaki nowej linii ... Ale od powyższego linku sugestia polegała na usunięciu/zamianie tych znaków - jest to dla mnie zła sugestia, ponieważ jeśli usunąć/zastąpić niektóre znaki z obrazu binarnego to po prostu być zepsuty.

Oczywiście, możliwe alternatywy odnoszą się do projektowania API: - dodać kilka funkcji, które zwracają reprezentacji base64 - dodać kilka funkcji, które zwracają link do obrazka

Gdybym nie naprawi to, zwrócę base64 reprezentację z serwera, ale nie podoba mi się taki sposób.

Czy istnieje jakiś sposób rozwiązania mojego problemu z obsługą obrazu binarnego z odpowiedzi, jak pokazano powyżej w części ekranu, czyż nie?

+0

Co używasz bok API? – FabianCook

+0

@FabianCook Gdzie dokładnie? Gdzie zasugerowałem zmianę API na powrót base64/url lub gdzie? Jeśli przeczytałeś mi uważnie, chcę znaleźć sposób, aby go nie używać i spróbować użyć innej metody/sztuczki. Aby uzyskać odpowiedź base64 od strony serwera - nie jest to problem, ale chcę znaleźć sposób, aby obsłużyć go jako obraz binarny. –

+0

Ahh okay. Rozejrzą się. Wstrzymać. – FabianCook

Odpowiedz

-3

bazy 64 danych obrazu jest dla mnie jak pracował

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

+0

Nieprawidłowe znaki powinny to zatrzymać. To o to pyta. – FabianCook

+0

Jest to projekt WebGL, nie tylko pokazujący go jako obraz statyczny, i znowu "nieprawidłowe znaki" ... –

1

im zgadywać używać escape na strunie przed przekazać go do funkcji, bez wywołania API nie mogę sprawdzić się.

testowe

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

powraca

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

To po prostu ucieka wszystkie znaki, należy uciec wszystkich nielegalnych znaków w ciągu

Test

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

RETUR ns

"%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

+0

Obawiam się, że ucieczka zepsuje obraz, więc nie można go wyświetlić po tym, jak niektóre znaki zostaną usunięte, ponieważ niektóre znaki i znaki binarne są wymagane do prawidłowego wyświetlania obrazu, ale dzięki za pomoc i spędzanie czasu dla mnie. –

+0

Proponuję uzyskać tę prośbę o funkcję. – FabianCook

0

Kwestia jesteś napotykające jest, że odpowiedź jest uważana za ciąg Unicode.Zobacz sekcję Unicode tutaj: window.btoa

Kilka rozwiązania oferowane są w tym post

+1

odpowiedź jest formatem binarnym, a nie tekstowym (więc nie może to być ciąg znaków Unicode, jak myślę), jeśli przyjrzysz się uważnie, przechwyciłem binarną treść obrazu PNG –

+0

@GeloVolro - Widziałem to . Zrobiłem kilka wyszukiwań, gdy otrzymałem ten sam błąd za pomocą btoa. Nie jestem pewien, czy Chrome wyświetla obiekty z cytatami, ale biorąc pod uwagę to, że wyświetla dane, wydaje mi się, że jest to ciąg znaków. Ponieważ wydaje się, że używasz jQuery, możesz użyć jQuery.type (odpowiedź), aby zobaczyć typ. – HungryBeagle

14

myślę częścią problemu jesteś uderzanie że jQuery.ajax ma not natywnie wspierać XHR2 rodzaje blob/arraybuffer które mogą obsługiwać ładnie dane binarne (patrz Reading binary files using jQuery.ajax).

Jeśli używasz natywnego obiektu XHR z xhr.responseType = 'arraybuffer', to odczytaj tablicę odpowiedzi i przekonwertuj ją na Base64, a otrzymasz to, czego chcesz.

Oto rozwiązanie, które działa na mnie:

// 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/

Produkuje base64 zakodowany wyjścia konsoli: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAIBAQIBAQICAgICAgICAw.....

+1

Dzięki, zajęło mi trochę czasu, aby uświadomić sobie, że to rozwiązało mój problem z powodu literówki, ale to działało dla mnie. – olleicua

+1

Pracowałem dla mnie, dziękuję za udostępnienie –

+1

Dziękuję bardzo, To uratowało nasz dzień ... cheeers ... –

3

zamiast zapętlenie przez blob z _arrayBufferToBase64 (), użycie apply(), aby wykonać konwersję, to 30 razy szybciej w przeglądarce i jest bardziej zwięzły

// 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) + '" />' \t 
 
});

+0

Włączyłem to do powyższej odpowiedzi. – fotinakis