So basically I want to add few images to zip file and be able to download it. I have two variables holding sources of images - pic1, pic2 and a global variable basePic for holding base64 string. I have a function to convert image to base64 :
var pic; //http://www.somesite.com/i/picture.jpg
var pic2; //http://www.somesite.com/i/picture2.jpg
var basePic;// base64 string of an image
function getBase64FromImageUrl(url) {
var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width =this.width;
canvas.height =this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
basePic=dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
};
img.src = url; // I was trying to put this after setAttribute, but it's the same effect
}
Later I'm trying to create a zip file and invoke this function like that:
var zip = new JSZip();
getBase64FromImageUrl(pic);
alert("random text"); // without it, it's just empty file added to zip
zip.file("picture.png",basePic, {base64: true});
getBase64FromImageUrl(pic2);
alert("random text");
zip.file("picture2.png",basePic, {base64: true});
zip.generateAsync({type:"blob"})
.then(function(content) {
saveAs(content, "example.zip");
});
This function works with one image, but it get's more random with more than one. If I run my code few times without refreshing the page it may get the result that I need. But most of the time in my zip file is just only second picture twice and I have to alert something after calling this function, because basePic would be empty without. I want to fix this function to be able, to easily convert multiple sources of images to base64 strings.
1.How to make this function work as it should, input_url -> output_base64, with multiple images ?
2.How to do that without the need to alert something after every call of that function ?
The problem is that the zipping process starts before the image(s) has loaded. The process of adding the files to the zip archive must start from inside the
onload
handler.However, there are several things to consider here as well:
Uint8Array
)I would propose the following approach instead:
XMLHttpRequest
s and request content asArrayBuffer
. This will allow you to load any kind of file directly to binary format which will increase performance and resources.generateAsync()
method and you should be done.Example
This is not a production-ready example and isn't intended to be, but it will show the main steps. Adjust to your scenario, add error handling and sanity checks where appropriate.