title: using dropzone.js with pica (or other image compression/resize libraries)
body: <p>I'd like to resize images before file upload using dropzone.js.  I've tried dropzone's built-in resizing feature, but it does not generate high quality images so I do not find it useful.  I was hoping to use pica (<a href="https://github.com/nodeca/image-blob-reduce" rel="nofollow noreferrer">https://github.com/nodeca/image-blob-reduce</a>) to process the files before they are sent to the server by dropzone.js.</p>
  <p>I have a simple proof of concept that works so far based on code I've cobbled together from other places.</p>
  <p>There are 2 issues...</p>
  <ol>
  <li><p>the progress bar doesn't work when uploading the image and the &quot;complete&quot; checkmark that ususally shows up on top of the image doesn't appear either when the upload is finished.  I'm guessing this is because I haven't copied over the values for the following into the new file</p>
  <blockquote>
  <p>previewElement: div.dz-preview.dz-image-preview</p>
  <p>previewTemplate: div.dz-preview.dz-image-preview</p>
  </blockquote>
  </li>
  <li><p>i cannot add a 2nd/3rd file.  i get the error</p>
  </li>
  </ol>
  <blockquote>
  <p>Uncaught (in promise) TypeError: Cannot read
  property 'toBlob' of undefined at reducer._create_blob</p>
  </blockquote>
  <p>Here is my semi-working code snippet...</p>
  <pre><code>  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/dropzone.min.css&quot; integrity=&quot;sha512-3g+prZHHfmnvE1HBLwUnVuunaPOob7dpksI7/v6UnF/rnKGwHf/GdEq9K7iEN7qTtW+S0iivTcGpeTBqqB04wA==&quot; crossorigin=&quot;anonymous&quot; /&gt;
      &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/basic.css&quot; integrity=&quot;sha512-Ucip2staDcls3OuwEeh5s9rRVYBsCA4HRr18+qd0Iz3nYpnfUeCIMh/82aHKeYgdaXGebmi9vcREw7YePXsutQ==&quot; crossorigin=&quot;anonymous&quot; /&gt;
   
     &lt;!-- dropzone.js --&gt;
     &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/min/dropzone.min.js&quot; integrity=&quot;sha512-9WciDs0XP20sojTJ9E7mChDXy6pcO0qHpwbEJID1YVavz2H6QBz5eLoDD8lseZOb2yGT8xDNIV7HIe1ZbuiDWg==&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  
     &lt;script src=&quot;js_libraries/pica/image-blob-reduce.js&quot;&gt;&lt;/script&gt;
      
  
  Dropzone.autoDiscover = false;
      var myDropzone = new Dropzone(&quot;#my-awesome-dropzone&quot;, {
          url: &quot;api/api_uploadPhotos.php&quot;,
          autoProcessQueue: false, // use: myDropzone.processQueue() to process
          addRemoveLinks: true,
  
          parallelUploads: 20,
          maxFiles: 20,
  
      });
  
      myDropzone.on(&quot;addedfile&quot;, function (origFile) {
  
          currFileType = origFile.type;
          currFileName = origFile.name;
          console.log('currFileType:' + currFileType);
          console.log('currFileName:' + currFileName);
  
          // get dimensions of image
          var url = URL.createObjectURL(origFile);
          var img = new Image;
          img.onload = function () {
  
              currFileWidth = img.width; // alert(img.width);
              currFileHeight = img.height;
              console.log('width: ' + currFileWidth);
              console.log('height: ' + currFileHeight);
              URL.revokeObjectURL(img.src);
  
              if (currFileType == 'image/jpeg') {
  
                  // ANCHOR: blob reducer
                  reducer._create_blob = function (env) {
                      return this.pica.toBlob(env.out_canvas, 'image/jpeg', 1.0)
                          .then(function (blob) {
                              env.out_blob = blob;
                              return env;
                          });
                  };
  
                  // reducer
                  reducer
                      .toBlob(
                          origFile, 
                          {
                              max: 1024,
                          }
                      )
                      .then(function (blob) {
                          console.log('done reducer');
  
                          document.getElementById('result').src = URL.createObjectURL(blob);
  
                           var newfile = new File([blob], &quot;file_name.jpeg&quot;, { type: &quot;image/jpeg&quot;, lastModified: Date.now() });
                          newfile['accepted'] = true;
                          newfile['status'] = 'queued';
                          newfile['upload'] = origFile['upload'];
  
                          var origFileIndex = myDropzone.files.indexOf(origFile);
                          myDropzone.files[origFileIndex] = newfile;
  
                      }); // reducer .then
              } // image/jpeg
  
          };
          img.src = url;
  
      });
  </code></pre>
  <p>the part where the error gets thrown is:</p>
  <pre><code>return this.pica.toBlob(env.out_canvas, 'image/jpeg', 1.0)
  </code></pre>
  <p>I'm not 100% set on using pica, but it produces good images, small file sizes, and is quick.  Fineuploader has integration with pica, but development/support for it was dropped 3 years ago.</p>
  <p>Any thoughts are much appreciated.  Thanks!</p>
  <p><strong>EDIT:</strong>
  looks like the following code is what was preventing the second image from being added.  commenting out this code, allowed the 2nd/3rd image to get added.  the code was taken from image-blob-reduce's github page, not 100% sure why i copied it during this test.</p>
  <pre><code>            /*
              reducer._create_blob = function (env) {
                  return this.pica.toBlob(env.out_canvas, 'image/jpeg', 1.0)
                      .then(function (blob) {
                          env.out_blob = blob;
                          return env;
                      });
              };
              */
  </code></pre>
  <p><strong>EDIT 2:</strong>
  I was right, copying over the</p>
  <pre><code>  newfile['previewElement'] = origFile['previewElement'];
    newfile['previewTemplate'] = origFile['previewTemplate'];
  </code></pre>
  <p>fixed the issue about the upload status and completion UI updates.</p>