I have a webapp that is saving images locally until they are ready to be sent to the server. When I save the images locally, I base64 encode them. Now I want to do a multipart file upload with these images.
So I need to convert the image back into binary form. I've tried using the FileReader to convert it back like this,
var fr = new FileReader();
fr.onloadend = function(binaryImage){
debugger;
binaryImage;
};
var base64Str = item.base64Image.substr(item.base64Image.indexOf("base64") + 7);
//var base64Str = item.base64Image;
fr.readAsBinaryString(base64Str);
but the onloadend event is never fired and there are no errors. Once I get the image I wont have trouble uploading it. Any ideas?
Thanks!
Not to familiar with FileReader, but I believe readAsBinaryString is expecting a Blob or File object. Passing it a string causes errors on my end. Try this:
var fr = new FileReader();
fr.onloadend = function(binaryImage){
debugger;
binaryImage;
};
var blob = new Blob([item.base64Image.
substr(item.base64Image.indexOf("base64") + 7)]);
fr.readAsBinaryString(blob);
I don't think this will give you want though. Check out this article for ways to encode/decode Base64: How can you encode to Base64 using Javascript?
Looks like you can use btoa() and atob() for web kit browsers.
Related
I am using react-easy-crop to allow users to modify their profile pictures after uploading. The problem I am experiencing is that after cropping, the image is returned in the form of a blob url like this: blob:http://localhost:3000/5e44190e-a087-4683-b3a4-dfce4a57ee62 which is unhelpful since it can only be viewed on my local machine.
I have tried converting it to a data url (which I understand can then be shared and viewed across browsers), using FileReader and the readAsDataURL() method like this:
let blob = await fetch(imageToCrop).then((r) => r.blob());
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
let base64data = reader.result;
console.log(base64data);
};
The base64data variable does return what I think I need, however all my attempts to then store this result in my state only return a null value.
Does anyone know what is the best way to handle this?
If you have this line in your code, delete it because it revoke your URL.
window.URL.revokeObjectURL(this.fileUrl);
If you need the base64 output of the cropped image, you can get it after using the canvas to crop it with canvas.toDataURL('image/jpeg'). This base64 string can then be shared to anyone or uploaded to a remote server.
This is basically the commented line in the getCroppedImg() function of this demo: https://codesandbox.io/s/q8q1mnr01w?file=/src/cropImage.js:2362-2562
BTW I guess you could also upload the blob to a remote server and store the image somewhere like AWS S3.
I'm using the management API to get all my installed apps and extensions. I want to send this information to server.
Every app/extension has an icon array, that has size and url.
The url is something like chrome://extension-icon/gmgpodcgeocidkeclglljo88jp9kclhhmmdacfo/32/0. I want to send it to my server in base64.
What I'm trying to do is something like:
var reader = new FileReader();
reader.onloadend = function() {
result = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
result = "";
}
Where file is a File object of the icon url. But I cannot find how to create an File object with this url format.
I've tried:
var fileUrlArray = ["chrome://extension-icon/gmgpodcgeocidkeclglljo88jp9kclhhmmdacfo/32/0"];
var file = new File(fileUrlArray, 'icon.png');
And as a result I got an absolutely wrong base64 string.
Any ideas about how to do it?
Thanks.
var oReq = new XMLHttpRequest();
var reader = new FileReader();
reader.onload = function(e) {
var rawData = reader.result;
oReq.open("POST", '/upload', true);
oReq.send(rawData);
console.log(rawData);
}
reader.readAsBinaryString(postObj);
// postObj is an image who's src is set to a data uri, taken via a webcam.
console.log(rawData) yields ==>
"PNG
IHDRÈÜÇ IDATx^d½idizw"##rϬ}ëîªÞfÃ!%2
ø£üølpµ0ù Q&É©¡,Ú2l²!æSeÃ$Y-ÉÎLïKuí{îáëºófe³§¦*3#Nó¾Ïr?÷³¼úOþÓùÉ tóne¸Øm.»ÙhÐtÃÅQ7<w''³nοg³Y·Èkóãn<Xì§G]·²Ø
ç]·8wÇ\å¨;á5vÁ°Ì»E¾?æ÷ywtÒuó¯ù{>Ïám]ÇëF£Qwt|\ßó5ä³NæÜÇ°^{r¿ùÜÁ|¡;>:êón0âß¼gûã6rm_ëgçõü4[vG¼gaa!?_à5#~³0\èxcß}Â}ú|ÜÓóóÅ!Ï=?â{®ã½ó^í½v'ü×úþÞ/×ñÏ}P®}Â÷ݸ;9fX¨?[àUÇ|?à^|þáb=çòɸ[æ·¬#7q]>giÜqÓ~#oq´èMdY4í3-.ùÈzÿü̺Íy
7Ľֺؿ\Ü6¯õ:Ü ß·5r-|ºv½½ôú¬w¶ìõáþ<{/íuí{ÞÎÚy¯Gì%kÎ}NfÓÚÞã5ݶÏÞÔr×
ø«Õッk¯õï</ëïçz¬ïso§ÙsƳü5öß»{ÛÝádÌñö ïgÍÿù¿üWÝƹÝøüX7øK?ùó ê¶/!Ë«ÝÂxÔ"
G.²Éxbæ]ñg#úýgé£Þ;¿ThƳ/ùòû(D¿Ã>2Þ-ð³7¯18"P<=ç>GSr±;r\à;³°<6ÎòZNAázndûûtù¼1ÇVGÁ¼^vܼ\3ÚÆu¸9×g]ÉñA V°0óîÍ£TÃY½ïdaM">ÆhÎF9ú¿](3¯¢xeÜõt
¢DÞN¾E¾oÈEy×q®?ÂÀ»z=Bó|,¯JáæzíýÞ¯ÿöï&äM!rϼWóQÛ^ÏÛÖ5÷ܤûåϸÛüûÃkôF©]ß¿óÜ1F¤üNëÍsM¯Qü²úYX:f¯DSßÌõ4D1eTÛûüvÿþlrpÐM'SÇuòµÈïù?øî½>è~â'~¢ü$
How can I interpret this in Python? On the server, this data shows up as:
'...\x7f\xc2\xb4r\xc2\x87\x1c\xc2\xaa\n-\xc2\x9c\xc2\xa6QF\xc2\xac\xc2\xb0tS\xc3\xa4\xc2\xb0;\xc3\x8cisL#\xc3\x98\xc2\x94E\xc3\x94\xc2\xb8Bz\xc3\xb0\xc3\xa9\xc2\xaa#8\xc2\x90\xc3\xbb\xc3\xa5>\xc3\xbaO\xc2\xa8\xc3\x81H\xc3\x91\xc2\xaf:i\xc2\x8a\xc2\x926\xc2\x8b\xc2\x81\xc3\xbc\xc3\xa1Y\xc3\x93\xc2\x9b\xc2\xbat\xc2\x8f\xc3\x9e~\xc2\xa3PH4\x02_\x04\xc2\xbf\xc2\x92\xc2\xb7\xc3\xad\xc2\x8f\xc3\x9e\xc3\xbf\xc2\xb8<\xc2\x91V\xc3\xa0\xc3\x8b\x1f\xc3\x88\xc3\x9f\xc2\xa2>)\x1d\xc3\x94eY=\xc3\x8ct\xc2\xa9+L^7\xc2\xa2I\xc3\x84\xc2\xba\x03\xc3\xb5!1f\xc3\x97\xc3\x81\xc3\xbfD\xc3\x87\xc3\xb7\x06\xc2\xaa\xc3\xafcz\xc3\xad(\xc3\xb5\xc2\xab\xc3\x96\xc3\xb5<\xc3\x8e\xc2\xab\x08\xc3\x81\xc2\x88\x0b\xc3\x8a;\xc3\x8e!v\xc3\x84\xc2\xb1?\xc2\x8bVn\x19t\xc3\x80\xc2\x8bT`:\x1c\xc3\x8b\xc2\x99\xc3\xb2\xc3\x9c\xc3\xbf\x0fCsXi\xc3\xa6z\xc3\xb3l\x00\x00\x00\x00IEND\xc2\xaeB`\xc2\x82'
Writing this to file as a PNG yields an invalid PNG. Any guidance on saving the image would be helpful.
You will need to convert your image's binary representation into Base64 before uploading - this makes it safe to work with when transferring data over HTTP.
When you receive the Base64 encoded image server-side, you can convert it back to binary, and write this to a file.
Client side code:
To convert to Base64, you need to use
fileReader.readAsDataURL( fileObject )
this automatically represents your data in a safe to upload via HTTP format.
Server side code:
import base64
coded_string = '''Q5YACgA...'''
binary = base64.b64decode(coded_string)
# now write binary to file...
open('/path/to/new_file.png', 'wb').write(rawData)
On the browser:
// Client Side:
var xhr = new XMLHttpRequest();
xhr.open('POST', uploadUrl);
xhr.send(base64EncodedItem);
On the server (I am using Flask/Python 2.x)
# Server Side:
import re
import uuid
# Obtain the base64 string
image_string = request.data
image_string = re.search(r'base64,(.*)', image_string).group(1)
# Generate a file name.
# We can assume PNG format in my specific implementation, but you could search
# the image_string variable to detect filetype.
output = open(str(uuid.uuid4()) + '.png', 'wb')
output.write(image_string.decode('base64'))
output.close()
This worked for me. Hope it helps others.
I am developing an application using phone gap. I capture image/audio/video and store its path in local storage. I need to fetch base64 of captured file and store it in the database and then sync it with server. Is that possible using javascript ?
I tried using FileReader API that phone gap provides but the function reader.onloadend() does not get executed.
Could manage to get base64 of image using a canvas but is it possible to get base64 for audio and video using canvas?
Thanks.
Yes It's possible to get the base64 of a media file
reader.onloadend() is not being called because you might have missed this line reader.readAsDataURL(file).
// here i have a file input and i am using the FileReader Api to read the content on it's change event ( i have no idea what is the event for capturing a media in phonegap
$("#file").change(function(e){
var file = e.currentTarget.files[0];
var FR = new FileReader();
FR.onload = function (encodedFile) {
//alert("onload is called.");
}
FR.onloadend = function (encodedFile) {
var src = encodedFile.target.result;
src = src.split("base64,");
// This is the base64 encoded string of that media file which you will be interested to store in the database(post to the server
var contentAsBase64EncodedString = src[1];
}
reader.readAsDataURL(file);
}
Using the filereader API it is possible to show a preview of the file, by reading the file with readAsDataURL
What I am trying to do is:
The user selects a file
A preview is shown, so that the user has some feedback.
If the user is satisfied, he submits the data to the backend.
Implementing step 3 can be done by re-reading the file with readAsBinaryString, but this looks problematic because the data could have disappeared or changed on disk. So What I would like is to convert the data returned from readAsDataURL to the format returned by readAsBinaryString. How can I do this?
Another alternative would be to submit the data to the backend as returned by readAsDataURL, but I would like to avoid that, since that would require special handling on the backend in my case.
Like CBroe said, you dont need to read the file twice.
JS :
handleFileSelectThumbFile(evt){
var files = evt.target.files;
var file = files[0];
// You can get the mime type like this.
var thumbMIME = files[0]['name'].split('.').pop();
if (files && file) {
var reader = new FileReader();
reader.onload = function(readerEvt) {
// Split the readerEvt.target.result by a ','.
// You can send the binaryString variable to the server.
// Its base64 encoded already.
var binaryString = readerEvt.target.result.split(',')[1];
// Set the image preview to the uploaded image.
$('.img-preview').prop('src', readerEvt.target.result);
}.bind(this);
reader.readAsDataURL(file);
}
}
HTML :
<input type="file" onChange={this.handleFileSelectThumbFile} required/>
<img src='http://placehold.it/300' class='img-preview'/>
You can read the MIME type from the first part of readerEvt as well. Look at CBroe's comment above.