Question

Okey, so what I want to do is download multiple images stored in an JavaScript array in AngularJS. I have not found any way of doing this in the form of "pure" images like .png .jpg etc (although if anyone knows how to do this please let me know). So I have turned to trying to zip the images with the help of jszip.js according to the description here : http://viralpatel.net/blogs/create-zip-file-javascript/

<li ng-click="download()"><a>Save to harddrive</a></li>

So this is the code called when the user clicks "download":

photodice.controller('ProjectController', function($scope, imageFactory) {
$scope.images = imageFactory.getImages();
$scope.download = function() {
   var zip = new JSZip();
   for (var x in $scope.images) {
      zip.folder("images").add("image" + x + ".png", $scope.images[x], {base64: true});
   }
   var content = zip.generate();
   console.log("content = "+ content);
   location.href="data:application/zip;base64," + content;
}
});

The problems occurs when the last line of code is executed, the browser crashes... I do not really understand how filedownloads work... Any suggestion or tips on what I should read up on would be greatly appreciated!

Update: I tried using Downloadify to solve my problem... and added some code:

$scope.download = function() {
var zip = new JSZip();
for (var x in $scope.images) {
    zip.folder("images").add("image" + x + ".jpg", $scope.images[x], {base64: true});
}
Downloadify.create('downloadify',{
  filename: function(){
    return "Images.zip";
},
  data: function(){
    return zip.generate();
},    
  onComplete: function(){ 
    alert('Your File Has Been Saved!'); 
},
  onCancel: function(){ 
    alert('You have cancelled the saving of this file.');
},
  onError: function(){ 
    alert('You must put something in the File Contents or there will be nothing to save!'); 
},
transparent: false,
swf: 'downloadify.swf',
downloadImage: 'img/download.png',
width: 100,
height: 30,
transparent: true,
append: false,
dataType: 'base64'
});

And now I can save the zip file:)

HOWEVER I still have a problem... the files in the zip are corrupt...

Normal non corrupt images look like this:

"data:image/jpeg;base64,iVBORw0KGgoAhE... ...c8+ocAAAAORK5CYII="

If I upload "currupt" images to my site agian and check the scope of the images that are corrupt the data looks like this:

"data:image/jpeg;base64,dataimage/jpegbase64iVBORw0KA... ...RNgAK5CYII="

Alternatively I remove the {base64: true}:

"data:image/jpeg;base64,ZGF0YTppbWF... ...WT1JLNUNZSUk9" (no "=" at the end)

What can I do about this?

Was it helpful?

Solution

I'm putting the answer here for future reference (because it was buried in the comments).

The issue comes from $scope.images[x] which contains a string, "data:image/jpeg;base64,iVBORw0KGgoAhE... ...c8+ocAAAAORK5CYII=". JSZip interprets the data:image/jpeg;base64, part as base64 content and generates corrupted images. To remove this part, you can do the following :

var base64 = $scope.images[x];
var index = base64.indexOf(",");
if (index !== -1) {
    base64 = base64.substring(index + 1, base64.length);
}
zip.folder("images").file("image" + x + ".jpg", base64, {base64: true});

Also, the add() method you use has been deleted in 2011 so you may want to update JSZip ! (but that may need some work : only folder() and remove() haven't changed between your version and the latest).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top