Get base64 image with reader.readAsArrayBuffer (file)

I am trying to get the contents of an image in a base64 string.

I originally did this with readAsDataURL , but because I want to check mimetype on the client side , it seems to me that I should use readAsArrayBuffer and also point to this site .

So, I succeeded in this:

 var reader = new FileReader(); reader.onloadend = function(event) { var base64 = reader.result; }; reader.readAsDataURL(event.target.files[0]); 

Online play

Now I have added mimetype confirmation, and I have the following:

 var reader = new FileReader(); reader.onloadend = function(event) { var realMimeType = getRealMimeType(reader); if (realMimeType !== 'unknown') { var emptyBufferArray = reader.result; //nothing }else{ alert("Invalid mime type!"); } }; reader.readAsArrayBuffer(event.target.files[0]); //<-- notice the difference 

Play online (not getting base64 string)

+7
javascript
source share
3 answers

The only way I found this is to use two different instances of FileReader , one inside the other.

Online Reproduction

Javascript

 $(document).on('change', '#upload', addBackgroundImage); function addBackgroundImage(event) { var reader = new FileReader(); var readerBase64 = new FileReader(); var image = event.target.files[0]; reader.onloadend = function() { var realMimeType = getRealMimeType(reader); if (realMimeType !== 'unknown') { readerBase64.readAsDataURL(image); } else { alert("Please upload a valid image file"); } }; reader.readAsArrayBuffer(image); readerBase64.onloadend = function(){ var base64 = this.result; $('.bg').css('background-image', 'url('+base64+')'); }; $('#upload').val(''); } function getRealMimeType(reader){ var arr = (new Uint8Array(reader.result)).subarray(0, 4); var header = ''; var realMimeType; for (var i = 0; i < arr.length; i++) { header += arr[i].toString(16); } // magic numbers: http://www.garykessler.net/library/file_sigs.html switch (header) { case "89504e47": realMimeType = "image/png"; break; case "47494638": realMimeType = "image/gif"; break; case "ffd8ffDB": case "ffd8ffe0": case "ffd8ffe1": case "ffd8ffe2": case "ffd8ffe3": case "ffd8ffe8": realMimeType = "image/jpeg"; break; default: realMimeType = "unknown"; // Or you can use the blob.type as fallback break; } return realMimeType; } 

HTML

 <input type="file" id="upload" /> <div class="bg"></div> 
+5
source share

I have not been able to use base64 yet, but I have found a way to do this using blob . If you find a way to do this using base64 , add your answer.

Right now, my image line looks like this, which I think will create some problems for me:

  background-image: url("blob:https%3A//fiddle.jshell.net/214b3c01-5b38-4aae-b839-e35cf57a5190"); 

I got a hint from the violin how to display the resulting image as a blob url

Then I just applied it to my code with a little improvement and voila !!

Play online Work in IE> 9, Chrome, Firefox ...

All code:

HTML

 <input type="file" id="upload" /> <div class="bg"></div> 

Javascript

 $(document).on('change', '#upload', addBackgroundImage); function addBackgroundImage(event) { var reader = new FileReader(); reader.onloadend = function(event) { var realMimeType = getRealMimeType(reader); if (realMimeType !== 'unknown') { var base64 = reader.result; var arrayBufferView = new Uint8Array( this.result ); var blob = new Blob( [ arrayBufferView ], { type: realMimeType } ); var urlCreator = window.URL || window.webkitURL || {}.createObjectURL; var imageUrl = urlCreator.createObjectURL( blob ); $('.bg').css('background-image', 'url('+imageUrl+')'); } else { alert("Please upload a valid image file"); } } reader.readAsArrayBuffer(event.target.files[0]); $('#upload').val(''); } function getRealMimeType(reader){ var arr = (new Uint8Array(reader.result)).subarray(0, 4); var header = ''; var realMimeType; for (var i = 0; i < arr.length; i++) { header += arr[i].toString(16); } // magic numbers: http://www.garykessler.net/library/file_sigs.html switch (header) { case "89504e47": realMimeType = "image/png"; break; case "47494638": realMimeType = "image/gif"; break; case "ffd8ffDB": case "ffd8ffe0": case "ffd8ffe1": case "ffd8ffe2": case "ffd8ffe3": case "ffd8ffe8": realMimeType = "image/jpeg"; break; default: realMimeType = "unknown"; // Or you can use the blob.type as fallback break; } return realMimeType; } 
+2
source share

You can try this "stolen" function :

 function arrayBufferToBase64(buffer) { let binary = ''; const bytes = new Uint8Array(buffer); const len = bytes.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return window.btoa(binary); } 
+1
source share

All Articles