Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Client side compression with HTML5 and Javascript

Am working on a web application and we allow users to upload files to our server. Am trying to do client side compression before uploading files to the server. What would be the better way to achieve this using HTML5 and JavaScript.

Thanks.

like image 727
Question Avatar asked Sep 19 '26 11:09

Question


2 Answers

In 2022 it's almost too simple, if the browser supports CompressionStream, FormData and Response.

In the example below I use FormData to collect all the fields from the form. Then I use the readable stream from the file, and pipe it though the compression stream. Then I use Response to read everything from the compressed stream and return it in a blob.

async function compress(file, encoding = 'gzip') {
  try {
    return {
      data: await new Response(file.stream().pipeThrough(new CompressionStream(encoding)), {
        headers: {
          'Content-Type': file.type
        },
      }).blob(),
      encoding,
    };
  } catch (error) {
    // If error, return the file uncompressed
    console.error(error.message);
    return {
      data: file,
      encoding: null
    };
  }
}

theForm.addEventListener(
  'submit',
  (event) => event.preventDefault()
)

theForm.addEventListener(
  'input',
  async function(event) {
    // collect all fields
    const fd = new FormData(theForm);

    // Get 'file handle' from imput elemen
    const file = fd.get('theFile');
    if (!file) return

    const encoding = fd.get('theEncoding');
    const compressed = await compress(file, encoding);

    theMessage.value = [
      'Compressed with', compressed.encoding,
      'Source file was', file.size, 'bytes',
      'and the compressed file', compressed.data.size,
      'saving', ((1 - compressed.data.size / file.size) * 100)
      .toFixed(0),
      '%.'
    ].join(' ')
  }
)
form>* {
  display: block;
  width: 100%;
}
<form id="theForm">
  <select name="theEncoding">
    <option>gzip</option>
    <option>deflate</option>
    <option>deflate-raw</option>
  </select>
  <input type="file" name="theFile" id="theFile">

</form>
<output id="theMessage"></output>
like image 90
some Avatar answered Sep 21 '26 01:09

some


The common mechanism to do what you want is using FileReader and a JavaScript client-side compression library (i.e. compressjs).

like image 32
heinob Avatar answered Sep 21 '26 01:09

heinob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!