Using compressorjs with React Native expo

Viewed 99

I'm trying to using the amazing compressorjs library in my React native expo project.

Currently, I have this:

import Compressor from 'compressorjs';

export const uploadPicture = async (uri, path) => {
    const blob = await new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.onload = function () {
            resolve(xhr.response);
        };
        xhr.onerror = function (e) {
            console.log(e);
            reject(new TypeError("Network request failed"));
        };
        xhr.responseType = "blob";
        xhr.open("GET", uri, true);
        xhr.send(null);
    });

    new Compressor(blob, { //<--- Problem
        quality: 0.6,
        maxWidth: 512,
        maxHeight: 512,
        success(result) {
            console.log(result)
        },
        error(err) {
            console.log(err.message)
        }
    })

    blob.close();

    //firebase stuff to upload after...
}

I'm assuming this doesn't work because compressorjs only allows File and Blob types and I'm inserting a Promise instead. But I have no clue what to do instead.

If anyone can point me into the right direction, that would be amazing! Thanks.

1 Answers

Consider using the fetch API response.blob method to get the image blob from the URI as opposed to using Ajax XMLHttpRequest

Like this -

Getting the blob via the URI
let blob = await fetch(uri).then(r => r.blob());

You can also take it a step further by getting the actual file from the blob, like this:

Getting the image file from the blob

let file = await fetch(url)
  .then((r) => r.blob())
  .then((blobFile) => new File([blobFile], "fileName", { type: "image/png" }));

Your finished code should look something like:

import Compressor from "compressorjs";

export const uploadPicture = async (uri, path) => {
  let blob = await fetch(uri).then(r => r.blob());

  new Compressor(blob, {
    ...
  });
};

OR this

import Compressor from "compressorjs";

export const uploadPicture = async (uri, path) => {
  let file = await fetch(url)
    .then((r) => r.blob())
    .then((blobFile) =>
       new File(
         [blobFile],
         "fileName",
         { type: "image/png" })
     );

  new Compressor(file, {
    ...
  });
};

Disclaimer

Please note that there's no guarantee that this suggestion will definitely solve your problem but it's DEFINITELY worth a shot.

Cheers.

Related