Trouble displaying binary stored in Azure Blob Storage on webpage - javascript

Using Windows Azure storage services, I have created a container and subsequently created a BlockBlob (a JPEG image) using the PUT Rest API. I can log into my Azure portal and download the image.
When I call the GET API Azure successfully returns me the blob in the response body -- and I think it's the same raw binary I uploaded.
When I call the GET API, I'm doing so via an XHR request in my JavaScript (Sencha Touch) application. I can see the response (the raw binary), but I cannot figure out how to read the binary into an image that I can display.
I've tried the following:
rawBinary = response.responseText;
encodedBinary = btoa(unescape(encodeURIComponent(rawBinary)));
img.setSrc('data:' + file.type + ';base64,' + encodedBinary);
...which gives me something like this:
data:image/jpeg;base64,77+977+977+977+9ABBKRklGAAEBAAABAAEAAO+/ve+/vQBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAO+/vWkABAAAAAEAAAAmAAAAAAAD77+9AQADAAAAAQABAADvv70CAAQAAAABAAAKIO+/vQMABAAAAAEAAAfvv70AAAAA77.......
This correctly sets a background URL on a DIV as a base64 encoded image... but nothing displays. It looks like a valid base64 string, and there are no errors in my console or network tabs. But nothing shows.
Can anyone help?
EDIT: Below is what the "binary" response looks like in the XHR response body:
����JFIF��XExifMM*�i&��
����C ��C��� "��
���}!1AQa"q2���#B��R��$3br�
...etc... VERY long response of unreadable characters

Can you try this jsfiddle by Vlad - http://jsfiddle.net/79NnG/
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
var img = new Image();
img.src = "data:image/jpeg;base64,"+hexToBase64(getBinary());
alert(hexToBase64(getBinary()));
document.body.appendChild(img);
Also this post should help you - How to display binary data as image - extjs 4

Related

Converting base64 data from json response into ms excel file using javascript

I've seen SO questions similar to my use case w/ angular and other server side platforms but not for pure javascript.
I have an app where I do a $.ajax and do a get call to an API, which returns a previously converted excel file (excel to base64); I need to re-convert this base64 data back into it's original form - i.e. into Excel file. I tried retracing the steps I took to convert the excel into base64, reversing some of them, but I'm not able to generate the original file. An excel file IS being generated, but it still has base64 data and therefore opens w/ errors and in a corrupted state.
Has anyone else successfully done this?
Below is my code and fiddle link: (I didn't add the base64 json data (responseData) here since it's large, but it's on the fiddle)
var bindata = window.atob(responseData);
function DownloadExcel() {
window.location.href = "data:application/vnd.ms-excel;base64, bindata"
}
var blob = new Blob([responseData], {type: 'application/vnd.ms-excel'});
if (window.navigator && window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob);
}
else {
var objectUrl = URL.createObjectURL(blob);
window.open(objectUrl);
}
jsfiddle link: https://jsfiddle.net/damon_matt/2ofz6xrd/

Downloading PDF from API using POST

Im trying to POST a request with some header information and other parameters to my api and then have it return a PDF file.
I've got the API communication working fine however I've tried several methods of viewing the PDF and none really work 100%.
The method below was found on stackoverflow and returns response data in PDF format however when it's converted to a blob to view it becomes blank.
[API]
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
ReturnInformationITEM rtn = GetPDFData(); //Comes back as Base64
response.Content = new ByteArrayContent(System.Convert.FromBase64String(rtn.Data));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return response;
[client]
var blob=new Blob([result], {type: 'application/pdf'});
var pom = document.getElementById("pdf" + $counter);
pom.setAttribute('href',window.URL.createObjectURL(blob));
pom.setAttribute('download',"Test.pdf");
pom.setAttribute('target','_blank');
'I did have a click event here but firefox ignores it so I have to pass the href back to the pom and manully click it'
If I alter the API to return base64 and have the client decode it before becoming a blob it will diaply the page but with an ugly blob URL and when saving in safari it doesnt recognise the 'download' attribute.
Does anyone know a method which can be used which will work cross browser and and allow for a filename to be prefilled? and if possible auto show the file upon returning the post data.
Thanks
Mark

image onload not firing javascript when source is base64 websocket data

I have a Custom helpdesk application that I am trying to run in javascript.
the program has a peice of code that runs on the customer's computer and sends an image to a autobahn websocket server which acts as a proxy to a image viewer which can send clicks and keystrokes back over the websockets. this is all currently working in python correctly however, when i try it in javascript, I cannot get my image loaded no matter what I do and I can't figure out what i am doing wrong.
This is the part of my javascript that is broken:
function onMessage(evt) {
if(evt.data.indexOf('[00000]')>=0){
var ar = evt.data.split('[00000]');
if (ar[0] == "[IMAGE]"){
var imgdata = evt.data.split('[22222]');
context.width = imgdata[0];
context.height = imgdata[1];
console.log(context.width + " " + context.height)
try{
var img = new Image();
img.src = imgdata[2];
context.drawImage(img,0,0);
console.log("IMAGE");
}catch(e){
console.log(e)
}
}else if(ar[0] == "[RETCONN]"){
console.log("Accepted!");
}
}
}
Below is some code from the server to try and clarify what is going on with the javascript.
def onMessage(self, payload, isBinary):
if isBinary:
print("Binary message received: {0} bytes".format(len(payload)))
else:
msg = payload.decode('utf8')
com, data, arg = msg.split('[11111]')
if com == ("[IMAGE]"):
for name, conn in clients.items():
if name == data:
conn.sendMessage(('[IMAGE]'+'[00000]'+arg).encode('utf8'))
break
and this is how the image is put together from the customer side:
data = image.tostring()
data = base64.b64encode(data)
self.sendMessage(('[IMAGE]' + '[11111]' + rid + '[11111]' + str(w) + '[22222]' + str(h) + '[22222]' + data).encode('utf8'))
Anyone have any ideas how what i am doing wrong in my javascript?
EDIT: i am aware that img.src is in the wrong location. moving to the right spot does not fix the issue
If you want to use base64 encoded image as a source for the image object, it needs to be in format:
data:image/png;base64,<base64 encoded image>
You need to prepend data:image/png;base64, to your base64 string
img.src = "data:image/png;base64,"+imgdata[2];
You are also parsing your messages wrong.
imgdata[0] is supposed to be your width, but it also includes [IMAGE][00000].
You probably want ar[1].split('[22222]'); instead of evt.data.split('[22222]');.
To avoid complications with encoding, I would recommend you to use JSON to encode your WebSocket messages.
Edit:
You are getting a broken image because image.tostring() returns raw image data, but with data:image/png;base64, it's expected to be in PNG format.
To get base64 encoded PNG data use this:
import io
buffer = io.BytesIO()
image.save(buffer, "png")
data = base64.b64encode(buffer.getvalue())

JPEG data obtained from FileReader doesn't match data in file

I'm trying to select a local JPEG file in the web browser via the HTML5 FileReader so I can submit it to a server without reloading the page. All the mechanics are working and I think I'm transferring and saving the exact data that JavaScript gave me, but the result is an invalid JPEG file on the server. Here's the basic code that demonstrates the problem:
<form name="add_photos">
​<input type=​"file" name=​"photo" id=​"photo" /><br />
​<input type=​"button" value=​"Upload" onclick=​"upload_photo()​;​" />​
</form>
<script type="text/javascript">
function upload_photo() {
file = document.add_photos.photo.files[0];
if (file) {
fileReader = new FileReader();
fileReader.onload = upload_photo_ready;
fileReader.readAsBinaryString(file);
}
}
function upload_photo_ready(event) {
data = event.target.result;
// alert(data);
URL = "submit.php";
ajax = new XMLHttpRequest();
ajax.open("POST", URL, 1);
ajax.setRequestHeader("Ajax-Request", "1");
ajax.send(data);
}
</script>
Then my PHP script does this:
$data = file_get_contents("php://input");
$filename = "test.jpg";
file_put_contents($filename, $data);
$result = imagecreatefromjpeg($filename);
That last line throws a PHP error "test.jpg is not a valid JPEG file." If I download the data back to my Mac and try to open it in Preview, Preview says the file "may be damaged or use a file format that Preview doesn’t recognize."
If I open both the original file on my desktop and the uploaded file on the server in text editors to inspect their contents, they are almost but not quite the same. The original file starts like this:
ˇÿˇ‡JFIFˇ˛;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90
But the uploaded file starts like this:
ÿØÿàJFIFÿþ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90
Interestingly, if I view the data in a JavaScript alert with the commented-out line above, it looks just like the uploaded file's data, so it seems as if the FileReader isn't giving the correct data at the very beginning, as opposed to a problem that is introduced while transferring or saving the data on the server. Can anyone explain this?
I'm using Safari 6 and I also tried Firefox 14.
UPDATE: I just figured out that if I skip the FileReader code and change ajax.send(data) to ajax.send(file), the image is transferred and saved correctly on the server. So my problem is basically solved, but I'll award the answer points to anyone who can explain why my original approach with readAsBinaryString didn't work.
Your problem lies with readAsBinaryString. This will transfer the binary data byte-for-byte into a string, so that you will send a text string to your PHP file. Now a text string always has an encoding; and when you use XmlHttpRequest to upload a string, by default it will use UTF-8.
So each character, which was originally supposed to represent one byte, will be encoded as UTF-8... which uses multiple bytes for each character with a code point above 127!
Your best best is to use readAsArrayBuffer instead of readAsBinaryString. This will avoid all the character set conversions (that are necessary when dealing with strings).

Base64 encode and image in Adobe Air

I am writing an Adobe Air app in HTML/JavaScript and I am trying to base64 encode an image so I can add it to and XML RPC request. I have tried many methods and nothing seems to work.
I see that actionscript has a Base64Encoder class that look like it would work, is there any way to utilize this in JavaScript?
Thanks #some for the link.
I used the btoa() function to base64 encode image data like this:
var loader = new air.URLLoader();
loader.dataFormat = air.URLLoaderDataFormat.BINARY;
loader.addEventListener(air.Event.COMPLETE,function(e){
var base64image = btoa(loader.data);
});
var req = new air.URLRequest('file://your_path_here');
loader.load(req);
I was trying to upload an image using metaWeblog.newMediaObject, but it turns out that the data doesn't need to be base64 encoded, so the binary value was all that was needed.

Categories

Resources