16

I have a function that currently downloads multiple images and saves them to a users "download" folder (Only works in Chrome)

I want to take this function to the next step and put these images in a single zip file.

Below is an example of my current code. I want to merge my code with the JSZip API I found online here.

I have done the bower install for this JSZip API already and included the script in my html.

Here is my code that works perfectly downloading multiple SINGLE images at once:

$scope.downloadPhotos = function() {
    var photoUrls = [];
    for (var x = 0; x < $scope.$parent.photos.length; x++) {

        var p = $scope.$parent.photos[x];
        if (p.isChecked) {
            photoUrls.push($scope.bucketUrl() + p.photoUrl);

        }
    }

    saveImage(photoUrls);
};



/*----this function  saveImage works great (only Chrome)-----*/
    function saveImage(urls) {
        var link = document.createElement('a');

        link.setAttribute('download', null);
        link.style.display = 'none';


        document.body.appendChild(link);

        for (var i = 0; i < urls.length; i++) {
            link.setAttribute('href', urls[i]);
            link.click();
        }

        document.body.removeChild(link);
    }

And here is the JSZip API code example to create a zip file with content in it:

function create_zip() {
    var zip = new JSZip();
    zip.add("hello1.txt", "Hello First World\n");
    zip.add("hello2.txt", "Hello Second World\n");
    content = zip.generate();
    location.href = "data:application/zip;base64," + content;
}

Now I'm just wondering how to combine the two to put my images into a zipfile. Thanks for your help!

Jason Brewer
  • 203
  • 1
  • 2
  • 8
  • It looks like because I have the image urls pulling from amazonS3, I dont have them stored in a place that is accessible - **ng-src** is loading those photos. So I need to figure out how to get data from **ng-src** if possible and then run the zip code. Is there a way to get that data from **ng-src** into my function? – Jason Brewer Aug 04 '15 at 16:56

4 Answers4

9

I put this together that will let you zip an array of image urls.

https://jsfiddle.net/jaitsujin/zrdgsjht/

You can manage zip folder structure by modifying this line

filename = filename.replace(/[\/\*\|\:\<\>\?\"\\]/gi, '').replace("httpsi.imgur.com","");
Jaitsujin
  • 131
  • 1
  • 7
4

To Download multiple files in Zip format we can use jsZip and FileSaver.js or if we are using Web API and Angularjs then we can create an API method to create zip archieve file at server and then in angularjs we can use $http post or get api call to download the file as zip file (We have to use filesaver to save the file in zip format). for example -

api call in angularjs -

function downloadFiles(files) {
            return $http.post(baseUrl + 'api/download/files', files, { responseType: 'arraybuffer' });
        }

call above function and on response use fileSaver.js method saveAs to save file in zip format for example -

//files - array input of files like http://www.example.com/file1.png', 'http://www.example.com/file2.jpeg', 'http://www.example.com/file3.jpg'];

    downloadFiles(files).then(function (response) {
        //on success
        var file = new Blob([response.data], { type: 'application/zip' });
        saveAs(file, 'example.zip');
    }, function (error) {
        //on error
        //write your code to handle error
    });
Ravindra Vairagi
  • 1,055
  • 15
  • 22
2

You should see this example. Currently, you just ask the browser to trigger the download of a file. If you want to create a zip file client side, your js code needs to access the content of the files with ajax calls (you will get CORS issues if they aren't stored on the same server).

Without copy/pasting the whole code, the example:

  • triggers ajax calls (with JSZipUtils but you can easily only use a responseType = "arraybuffer" if you only supports recent browsers)
  • wrap them into promises (jQuery promises here but you can use your own)
  • add the result into a zip object
  • wait for all promises to complete before triggering a download
David Duponchel
  • 3,959
  • 3
  • 28
  • 36
1
function downloadImageAsZip(imageUrl){
        var zip = new JSZip();
        var img = new Image();
        img.crossOrigin = 'Anonymous';
        img.src = imageUrl;
        img.onload = function() {
        $scope.count2++;

        var canvas = document.createElement('CANVAS');
        var ctx = canvas.getContext('2d');
        var dataURL;
        canvas.height = img.height;
        canvas.width = img.width;
        ctx.drawImage(this, 0, 0);
        ctx.enabled = false;
        dataURL = canvas.toDataURL("Canvas");
        canvas = null;
        //var base64String = dataURL.replace("/^data:image\/(png|jpg);base64,/", "");
        var base64String = dataURL.replace("data:image/png;base64,", "");
            zip.file("ImageName", base64String, {base64: true});

             zip.generateAsync({type:"blob"}).then(function(content) {
                        saveAs(content, "ZipFileName.zip");
             });

        }

    }
Vic Key
  • 37
  • 4