I am trying to format an uploaded .png file in my angular front-end so that it can be stored in a database. I am having some issues which I have replicated in this single function. I am taking the data field passed into this function, which represents the png file and encoding it in base64. However, I can't tell if it is working. In this example, I encode the item and then instantly decode it, but the outputs don't equal each other?
addImage(data: any): Observable<File> {
console.log('original', data);
const encodedImg: Image = new Image();
encodedImg.img = {data: btoa(data), contentType: 'image/png'};
console.log('encoded', encodedImg);
console.log('final', atob(encodedImg.img.data), encodedImg.img.contentType);
return this.http.post<File>('/api/image', encodedImg);
}
I have an image that is stored in a buffer. I'm trying to set it as the window icon, but I can't find a way to do so. There is no path to the image, so I can't just use win.setIcon('path/to/image').
I tried to do the following, to no success.
win.setIcon(buffer); // giving the buffer by itself
win.setIcon(buffer.toString('base64')); // giving the buffer as base64
win.setIcon(`data:image/png;base64,${buffer.toString('base64')}`); // giving as base64 url
let imageObject = new Image();
imageObject.src = `data:image/png;base64,${buffer.toString('base64')}`;
win.setIcon(imageObject); // giving image object
According to Electron's documentation, BrowserWindow.setIcon () takes either a string or a NativeImage, a data type provided by Electron. You can convert your buffer to a NativeImage by using the following code:
const { nativeImage } = require ("electron");
win.setIcon (nativeImage.createFromBuffer (buffer));
If that does not help, you can also pass your buffer as a Base 64 string in a data URL (like you have tried before) to the function createFromDataURL. For more information, see the documentation on NativeImage. It is also worth noting that you can pass advanced options to the createFromBuffer function to give Electron more hints about how to display your icon.
So i am dropping a .txt file in an uploader which is converting it into base64 data like this:
const {getRootProps, getInputProps} = useDropzone({
onDrop: async acceptedFiles => {
let font = ''; // its not actually a font just reusing some code i'll change it later its a .txt file so wherever you see font assume its NOT a font.
let reader = new FileReader();
let filename = acceptedFiles[0].name.split(".")[0];
console.log(filename);
reader.readAsDataURL(acceptedFiles[0]);
reader.onload = await function (){
font = reader.result;
console.log(font);
dispatch({type:'SET_FILES',payload:font})
};
setFontSet(true);
}
});
Then a POST request is made to the node js server and I indeed receive the base64 value. I then proceed to convert it back into a .txt file by writing it into a file called signals.txt like this:
server.post('/putInDB',(req,res)=>{
console.log(req.body);
var bitmap = new Buffer(req.body.data, 'base64');
let dirpath = `${process.cwd()}/signals.txt`;
let signalPath = path.normalize(dirpath);
connection.connect();
fs.writeFile(signalPath, bitmap, async (err) => {
if (err) throw err;
console.log('Successfully updated the file data');
//all the ending brackets and stuff
Now the thing is the orignal file looks like this :
Time,1,2,3,4,5,6,7,8,9,10,11,12
0.000000,7.250553,14.951141,5.550423,2.850217,-1.050080,-3.050233,1.850141,2.850217,-3.150240,1.350103,-2.950225,1.150088
But the file when writing back from base64 looks like this :
u«Zµìmþ™ZŠvÚ±î¸Time,1,2,3,4,5,6,7,8,9,10,11,12
0.000000,1.250095,0.250019,-4.150317,-0.350027,3.650278,1.950149,0.950072,-1.250095,-1.150088,-7.750591,-1.850141,-0.050004
See the weird characters in the beginning ? Why is this happening.
Remember to read up on what the functions you use do, because you're using readAsDataURL which does not give you the base64 encoded version of your data: it gives you Data-URL, and Data-URLs have a header prefix to tell URL parsers what kind of data this will be, and how to decode the data directly following the header.
To quote the MDN article:
Note: The blob's result cannot be directly decoded as Base64 without first removing the Data-URL declaration preceding the Base64-encoded data. To retrieve only the Base64 encoded string, first remove data:*/*;base64, from the result.
If you don't, blindly converting the Data-URL from base64 to plain text will give you some nonsense data at the start:
> Buffer.from('data:*/*;base64', 'base64').toString('utf-8')
'u�Z���{�'
Which raises another point: you would have caught this with POST data validation, because the Data-URL that you sent contains characters that are not allowed in base64. POST validation is always a good idea.
I know this isn't the exact code, but it is difficult to reproduce your problem with the code you provided. But the data you are sending needs to be a URL/URI encoded form.
So essentially:
encodeURI(base64data);
Encode URI is built into javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
EDIT:
I saw you used the function readDataAsUrl(), but try using the encodeURI function and then readDataAsUrl().
I am trying to convert a binary blob which is fetched from database into an image which I can render with an <img>-Tag.
In my Laravel backend I return the blob/data like this:
$user = User::find($id);
$user->photo = utf8_encode($user->photo); // $user->photo is saved as blob in MySQL database
return $user;
The reason why I use utf8_encode is that the data is returned as JSON.
In VueJS I did try the following to render the image:
<input type="file" #change="onFileSelect">
<img :src="setImage(userdata.photo)">
setImage(image) {
let objurl = window.URL.createObjectURL(new Blob([image]));
return objurl;
}
onFileSelect(e) {
this.userdata.photo = e.target.files[0];
}
If I select a file in input the image is rendered accordingly. But when I fetch my data from server it should load the saved image.
If I console.log(image) inside the setImage(image) method after the server request I get the following output:
PNG
IHDRu<ÔFiCCPICC ProfileHWXSÉ[RIh¤ÞD)Ò¥Ð"Hl$PBL"vdQÁµØÐUE×ÈZ±E±÷e],ØPyºú½÷¾w¾ïÜûçÌÿ̽w®Dj+ÎÆ3Ç¥¤2I0t.O&aÅÆF(÷Ê»ëQܯ8+¸~ÿ¯¢ÃÈx ±§óe¼\÷ð$Ò|ÞÐn55_¢À ÖÂ!(p¦
(pº
W*}âØïLãr¥h6C;³ y4oBì"æÄh!à ¹|# §ÀÐاÇùÎôAN.7s«jQ
9D$äp§ýíøß#a&FÄ)j}»©À4»ÅéÑ1ëBüAÄWúCRòD?j±aÏÄ.|nH$Ä&s¢£ÔöôQb¸BÐBQ>'A=w#¯æ¬æÅÅà)¥ÛÀãüOȳYjþBgÿm0!Y3F-%EC¬ ±,;>RåY ÙÑ>Ry"k}âð?6)C§öæÊêÅEh5®Ê&D¨yvð¸Êü
!nY<Ù¸¨ZøPUíØ%8Q]/Ö!ÉSÏ}-ÉUûãTAN¸Ân ±¬ ^=ÈRÅGKòcTyâéYÜѱª|ðBØ 0j:ÈY#ÔÖÝÔ
©FÂHA&gµeF²rD¯ñ üÈç+G Ú¿ZUWg¡-PÎÈO Î þ+g£%ÇÐ"ú):æU1ö³-Qj|©5àI%#aDÜÀýð(x
ê{ã>Ù~ó'bG°fìvHWÑcå*§Ì'ò~ÇUÇTtRæRïÒåòY5/(T¼;O2M*Êæ3YðÍ/rļáÃn.®ðø¨^S=ßÄHçm|nGi÷÷÷øf#ãP¨ÝßlöЯpf>O.-PÙpÅ¿PZð2fÀ
If I pass that stuff to my setImage() method I do not get any error. The blob URL is created but the <img> Tag just shows an "empty" image.
And so on. Is there a way how I can convert this utf8_encoded blob into something useful?
I cannot comment, so had to post as an answer. I will remove if needed.
You could use a library to handle blob parsing on the front-end.
https://www.npmjs.com/package/blob-util
That library has built in ES module support, so should work out-of-the-box with Vue.
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.