Convert Image to Binary Data or String in Javascript - javascript

I am working on uploading image file to TWITPIC using XMLHttp Request on a Chrome Extension . I need to send the image as payload. Is there a way to do this ? I found this link Convert an image into binary data in javascript
But that works on image tags. i need a way to specify image file path and upload image to TWITPIC.
I came to know about FileReader API with HTML 5. Is there any way to work using that??. It should work on a local file.
Does Chrome Extension support FileReader API without running a localhost server ??

I found the answer myself. Chrome Extensions does support FileReader API of HTML 5. So just the code below works simple.
var reader = new FileReader();
reader.readAsDataURL(f);

You can use this to get the binary data of an image using XMLHTTPRequests, I used it recently for a similar purpose:
var dataToBinary = function(data){
var data_string = "";
for(var i=0; i<data.length; i++){
data_string += String.fromCharCode(data[i].charCodeAt(0) & 0xff);
}
return data_string;
};
$.ajax("http://some.site.com/myImage.jpg", {
success: function(data){
binary = dataToBinary(data);
//or: 'binary = data', dataToBinary might not be needed
},
mimeType: "text/plain; charset=x-user-defined"
});
And the binary data is stored in the binary variable.

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/

Decode Base64 encoded PDF content in browser

We transform HTML to PDF in the backend (PHP) using dompdf. The generated output from dompdf is Base64 encoded with
$output = $dompdf->output();
base64_encode($output);
This Base64 encoded content is saved as a file on the server. When we decode this file content like this:
cat /tmp/55acbaa9600f4 | base64 -D > test.pdf
we get a proper PDF file.
But when we transfer the Base64 content to the client as a string value inside a JSON object (the server provides a RESTful API...):
{
"file_data": "...the base64 string..."
}
And decode it with atob() and then create a Blob object to download the file later on, the PDF is always "empty"/broken.
$scope.downloadFileData = function(doc) {
DocumentService.getFileData(doc).then(function(data) {
var decodedFileData = atob(data.file_data);
var file = new Blob([decodedFileData], { type: doc.file_type });
saveAs(file, doc.title + '.' + doc.extension);
});
};
When we log the decoded content, it seems that the content is "broken", because several symbols are not the same as when we decode the content on the server using base64 -D.
When we encode/decode the content of simple text/plain documents, it's working as expected. But all binary (or not ASCII formats) are not working.
We have searched the web for many hours, but didn't find a solution for this that works for us. Does anyone have the same problem and can provide us with a working solution? Thanks in advance!
This is a example for a on the server Base64 encoded content of a PDF document:
JVBERi0xLjMKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZwovT3V0bGluZXMgMiAwIFIKL1BhZ2VzIDMgMCBSID4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9PdXRsaW5lcyAvQ291bnQgMCA+PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMKL0tpZHMgWzYgMCBSCl0KL0NvdW50IDEKL1Jlc291cmNlcyA8PAovUHJvY1NldCA0IDAgUgovRm9udCA8PCAKL0YxIDggMCBSCj4+Cj4+Ci9NZWRpYUJveCBbMC4wMDAgMC4wMDAgNjEyLjAwMCA3OTIuMDAwXQogPj4KZW5kb2JqCjQgMCBvYmoKWy9QREYgL1RleHQgXQplbmRvYmoKNSAwIG9iago8PAovQ3JlYXRvciAoRE9NUERGKQovQ3JlYXRpb25EYXRlIChEOjIwMTUwNzIwMTMzMzIzKzAyJzAwJykKL01vZERhdGUgKEQ6MjAxNTA3MjAxMzMzMjMrMDInMDAnKQo+PgplbmRvYmoKNiAwIG9iago8PCAvVHlwZSAvUGFnZQovUGFyZW50IDMgMCBSCi9Db250ZW50cyA3IDAgUgo+PgplbmRvYmoKNyAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDY2ID4+CnN0cmVhbQp4nOMy0DMwMFBAJovSuZxCFIxN9AwMzRTMDS31DCxNFUJSFPTdDBWMgKIKIWkKCtEaIanFJZqxCiFeCq4hAO4PD0MKZW5kc3RyZWFtCmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovTmFtZSAvRjEKL0Jhc2VGb250IC9UaW1lcy1Cb2xkCi9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nCj4+CmVuZG9iagp4cmVmCjAgOQowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDggMDAwMDAgbiAKMDAwMDAwMDA3MyAwMDAwMCBuIAowMDAwMDAwMTE5IDAwMDAwIG4gCjAwMDAwMDAyNzMgMDAwMDAgbiAKMDAwMDAwMDMwMiAwMDAwMCBuIAowMDAwMDAwNDE2IDAwMDAwIG4gCjAwMDAwMDA0NzkgMDAwMDAgbiAKMDAwMDAwMDYxNiAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDkKL1Jvb3QgMSAwIFIKL0luZm8gNSAwIFIKPj4Kc3RhcnR4cmVmCjcyNQolJUVPRgo=
If you atob() this, you don't get the same result as on the console with base64 -D. Why?
Your issue looks identical to the one I needed to solve recently.
Here is what worked for me:
const binaryImg = atob(base64String);
const length = binaryImg.length;
const arrayBuffer = new ArrayBuffer(length);
const uintArray = new Uint8Array(arrayBuffer);
for (let i = 0; i < length; i++) {
uintArray[i] = binaryImg.charCodeAt(i);
}
const fileBlob = new Blob([uintArray], { type: 'application/pdf' });
saveAs(fileBlob, 'filename.pdf');
It seems that only doing a base64 decode is not enough...you need to put the result into a Uint8Array. Otherwise, the pdf pages appear blank.
I found this solution here:
https://github.com/sayanee/angularjs-pdf/issues/110#issuecomment-579988190
You can use btoa() and atob() work in some browsers:
For Exa.
var enc = btoa("this is some text");
alert(enc);
alert(atob(enc));
To JSON and base64 are completely independent.
Here's a JSON stringifier/parser (and direct GitHub link).
Here's a base64 Q&A. Here's another one.

Download base64 pdf with IE9

I have a base64 pdf that I get from external system.
I want to be able to download this pdf in IE9 with JavaScript and this is a problem since IE9 doesn't support DATA URI for pdf.
Please help me.
Thanks!
You should use Adobe Flash based plugin Downloadify (see the demo) to allow users download file in IE9.
You may check if the current browser supports dataURI or not using the following js function:
function CheckDataURISupport(){
var result = true;
var checkDataURISupportImage = new Image();
checkDataURISupportImage.onload = checkDataURISupportImage.onerror = function(){
if(this.width != 1 || this.height != 1){
result = false;
}
}
checkDataURISupportImage.src = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";
// check if we have datauri support in current browser - end
return result;
}
Downloadify.js is a great solution for your case. Just be careful with options. There should be
'dataType': 'base64'
'data:' string representation of pdf in base64 format
Also be sure that your link/button has inserted 'flash code' by downloadify plugin (check source code after downloadify.create() initialization). Also you can check if your base64 has data:application/pdf;base64, type at the beginning.

How to upload base64 encoded image data to S3 using JavaScript only?

I have a rails app on Heroku (cedar env). It has a page where I render the canvas data into an image using toDataURL() method. I'm trying to upload the returned base64 image data string directly to s3 using JavaScript (bypassing the server-side). The problem is that since this isn't a file, how do I upload the base64 encoded data directly to S3 and save it as a file there?
I have found a way to do this. After a lot of searching a looking at different tutorials.
You have to convert the Data URI to a blob and then upload that file to S3 using CORS, if you are working with multiple files I have separate XHR requests for each.
I found this function which turns your the Data URI into a blob which can then be uploaded to S3 directly using CORS (Convert Data URI to Blob )
function dataURItoBlob(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
}
Here is a great tutorial on uploading directly to S3, you will need to customise the code to allow for the blob instead of files.
Jamcoope's answer is very good, however the blob constructor is not supported by all browsers. Most notably android 4.1 and android 4.3. There are Blob polyfills, but xhr.send(...) will not work with the polyfill. The best bet is something like this:
var u = dataURI.split(',')[1],
binary = atob(u),
array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
var typedArray = Uint8Array(array);
// now typedArray.buffer can be passed to xhr.send
If anyone cares: here is the coffescript version of the function given above!
convertToBlob = (base64) ->
binary = atob base64.split(',')[1]
array = []
for i in [0...binary.length]
array.push binary.charCodeAt i
new Blob [new Uint8Array array], {type: 'image/jpeg'}
Not sure if OP has already solved this, but I'm working on a very similar feature. In doing a little research, I came across these articles that might be helpful.
http://blog.danguer.com/2011/10/25/upload-s3-files-directly-with-ajax/
http://www.tweetegy.com/2012/01/save-an-image-file-directly-to-s3-from-a-web-browser-using-html5-and-backbone-js/

Base64 encode/decode and download content generated in URL

I am generating a string through JavaScript and I need to download it to a text file with a predefined dynamic filename. This way there will be no room for error by employees.
This is obviously not possible in JavaScript due to security issues. However, from what I have read it should be possible with base64 encoding.
I managed to encode the string and open a url with the decoded data. The string has been decoded successfully in this URL. The format is as follows:
var data = 'data:text/plain;base64,'+L_EncodedData;
document.location = data;
I need to open a file dialog with the decoded data so the employees can download the content generated in this URL.
Any help?
Many thanks in advance
If you're still looking for an answer to this, check out my answer here. This is how I would adapt it for your needs.
// Convert the Base64 string back to text.
var txt = atob(data.reportBase64Bytes);
// Blob for saving.
var blob = new Blob([byteString], { type: "text/plain" });
// Tell the browser to save as report.txt.
saveAs(blob, "report.txt");
If you use this, make sure you grab the polyfills that I mention in the other post.
This block is fixed.
window.OpenWindowForBase64 = function(url, callback) {
var image = new Image();
image.src = url;
var w = window.open("");
w.document.write(image.outerHTML);
if (callback) {
callback(url);
}
}

Categories

Resources