Show image from local zip with JSZip
Asked Answered
B

1

10

I have a zip with a bunch of folders containing one or more png-files each that I want to render to the DOM.

zip.loadAsync(file) .then(function(zip) {
  zip.file('textfile.txt')
   .async("string")
   .then(function (content) { console.log(content); });

}, function (e) {
     console.log("Error reading " + file.name + " : " + e.message); });

I can read a text file, but I'm stuck when it comes to getting the binary data from an image file.

My thought is that I should use URL.createObjectURL( blob ) to create a reference to the files and then render <img id="output" src="blob:null/341e9aeb-a794-4033-87f5-e8d075e9868a"> for each image in the zip.

How can I get the images from the zip?

Thanks!

Bowlds answered 13/10, 2016 at 18:39 Comment(0)
O
12

You can use .async("base64") to return base64 representation of image file; prepend data:[<mediatype>][;base64], to content where content is <data>; set img src to data URI string.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>

<head>
  <script>
    window.onload = function() {
      var zip = new JSZip();

      function loadImage(url) {
        var request = new XMLHttpRequest();
        request.open("GET", url);
        request.responseType = "blob";
        request.onload = function() {
          console.log(this.response);
          var response = this.response;
          var filename = "image." + response.type.split("/")[1];
          zip.file(filename, response);
          zip.file(filename)
            .async("base64")
            .then(function(content) {
                console.log(content);
                var img = new Image;
                img.onload = function() {
                  document.body.appendChild(this)
                }
                img.src = "data:" + response.type + ";base64," + content;
              },
              function(e) {
                console.log("Error reading " 
                            + file.name + " : " 
                            + e.message);
              });
          
        }
        request.send()
      }

      loadImage("https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150")
    }
  </script>
</head>

<body>
</body>

Alternatively, using .async("arraybuffer"), Blob(), Uint8Array(), URL.createObjectURL()

zip.file(filename)
  .async("arraybuffer")
  .then(function(content) {
      console.log(content);
      var buffer = new Uint8Array(content);
      var blob = new Blob([buffer.buffer]);
      console.log(blob);
      var img = new Image;
      img.onload = function() {
        document.body.appendChild(this)
      }
      img.src = URL.createObjectURL(blob);
    },
    function(e) {
      console.log("Error reading " + file.name + " : " + e.message);
    });

plnkr http://plnkr.co/edit/WURdaAqog3KTyBs4Kirj?p=preview

Orndorff answered 13/10, 2016 at 19:31 Comment(5)
@Bowlds Creating Blob from data URI is described at #4999408Orndorff
Not sure I follow... You get the picture with a XMLHttpRequest. Is this similar to getting it from a zip?Bowlds
@Bowlds Getting the image using XMLHttpRequest was for demonstration purpose. You already have images in a zip instance. The main gist of Answer is to use .async("base64") to retrieve file as base64 string, then prepend necessary data: protocol, MIME type and base64 to create a data URI. You can alternatively create a Blob from base64Orndorff
You could also use .async("arraybuffer") then create a Blob and use Blob URL at img src.Orndorff
@Bowlds See updated post. Included approach using .async("arraybuffer"), Blob(), URL.createObjectURL()Orndorff

© 2022 - 2024 — McMap. All rights reserved.