Michael Schwartz Michael Schwartz - 4 months ago 117
Javascript Question

Load Image with Filereader API and Zip It Using JSZip

I'm trying to load an image using fileready api...

Save it in a newly made zip file made using jszip...

with the name

logo.png
but my problem is getting the image to save in the zip from filereader.

If anyone can help it'd be greatly appreciated.



$(document).ready(function() {

$(".load").on("change", function(evt) {
var file = evt.target.files;
var reader = new FileReader();

reader.onload = (function(event) {
return function(e) {
var imgBinary = e.target.result;
var imgz = new Image();
imgz.attr("src", event.target.result);
imgz.attr("width", 128);
imgz.attr("height", 128);
holder.html("");
holder.append(imgz);
};
});
reader.readAsDataURL(file);
// reader.readAsArrayBuffer(file);

// Download Zip
$(".download").on("click", function() {
var zip = new JSZip();
zip.load(webAppZipBinary);
zip.file("Hello.txt", "Hello World\n");
var content = zip.generate({type:"blob"});
// see FileSaver.js
saveAs(content, theFile.name.substr(theFile.name.length - theFile.name.length, theFile.name.length - 4) + "-win.zip");
});

return false;
});


// Trigger Load Image
$(".trigload").click(function() {
$("input").trigger("click");
});
});

@import url("http://necolas.github.io/normalize.css/3.0.1/normalize.css");

.hide {
display: none;
}

.holder {
text-align: center;
}

.fr {
float: right;
}

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip-utils/dist/jszip-utils.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/vendor/FileSaver.js"></script>

<input type="file" class="hide">
<a class="trigload" href="javascript:void(0)">Load Image</a>
<a class="download fr" href="javascript:void(0)">Download</a>
<div class="holder"></div>




Answer

What I changed:

  • I don't think we can use an ArrayBuffer to preview an image, I now have two Readers: one for the preview, one for JSZip (which performs way better on ArrayBuffer than on strings)
  • I moved the "download code" after the Reader: we need to read the Blob, add the content to the zip and then prepare the download link. You have other ways to do it, that's just an example.
  • I added the logo.png in the zip.
  • I fixed minor errors (missing css class, Image#attr doesn't exist, etc)

function displayPreview(file) {

  var reader = new FileReader();

  reader.onload = function(e) {
    var holder = $(".holder");
    var imgUrl = e.target.result;
    var imgz = $("<img>");
    imgz.attr("src", imgUrl);
    imgz.attr("width", 128);
    imgz.attr("height", 128);
    holder.html("");
    holder.append(imgz);
  };
  reader.readAsDataURL(file);
}

$(document).ready(function() {
  $(".load").on("change", function(evt) {
    var file = evt.target.files[0];
    displayPreview(file);

    var reader = new FileReader();

    reader.onload = function(e) {
      
      // Download Zip
      $(".download").on("click", function() {
        var zip = new JSZip();
        zip.file("logo.png", e.target.result);
        var content = zip.generate({type:"blob"});
        // see FileSaver.js
        saveAs(content, "test-win.zip");
      });
    };
    reader.readAsArrayBuffer(file);

    return false;
  });


  // Trigger Load Image
  $(".trigload").click(function() {
    $("input").trigger("click");
  });
});
@import url("http://necolas.github.io/normalize.css/3.0.1/normalize.css");

.hide {
  display: none;
}

.holder {
  text-align: center;
}

.fr {
  float: right;
}
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip-utils/dist/jszip-utils.js"></script>
<script type="text/javascript" src="http://stuk.github.io/jszip/vendor/FileSaver.js"></script>

<input type="file" class="hide load">
<a class="trigload" href="javascript:void(0)">Load Image</a>
<a class="download fr" href="javascript:void(0)">Download</a>
<div class="holder"></div>