Compress Images Before Upload in React with React Image File Resizer

How to manipulate our image before uploading in a React app.

Photo by Viktor Talashuk on UnsplashPhoto by Viktor Talashuk on Unsplash

The React Image File Resizer lets us compress and manipulate our images before we upload them.

In this article, we'll look at how to manipulate our image before uploading in a React app.

Installation

We can install the package by running:

npm i react-image-file-resizer

or

yarn add react-image-file-resizer

Compressing and Manipulating Images

We can compress and manipulate our image that we select from a file input.

To do that, we write:

import React from "react";
import Resizer from "react-image-file-resizer";

const resizeFile = (file) =>
  new Promise((resolve) => {
    Resizer.imageFileResizer(
      file,
      300,
      400,
      "JPEG",
      80,
      0,
      (uri) => {
        resolve(uri);
      },
      "base64"
    );
  });

export default function App() {
  const onChange = async (event) => {
    const file = event.target.files[0];
    const image = await resizeFile(file);
    console.log(image);
  };

  return (
    <div className="App">
      <input onChange={onChange} type="file" />
    </div>
  );
}

We have the resizeFile function that takes the image file and returns the promise to resize and compress the file.

The first argument is the file object.

The 2nd and 3rd are the width and height.

The 4th is the format to convert to.

The 5th is the quality of the image from 0 to 100.

The 6th is the rotation of the image.

The 7th is a function for getting the new image URI.

The 8th is the format.

It takes 2 more arguments for the min-width and height.

In the onChange handler, we get the file from the file input.

Once we did that we can do the upload.

Upload the File

To upload the file, we write:

import React from "react";
import Resizer from "react-image-file-resizer";

const resizeFile = (file) =>
  new Promise((resolve) => {
    Resizer.imageFileResizer(
      file,
      300,
      400,
      "JPEG",
      80,
      0,
      (uri) => {
        resolve(uri);
      },
      "base64"
    );
  });

const dataURIToBlob = (dataURI) => {
  const splitDataURI = dataURI.split(",");
  const byteString =
    splitDataURI[0].indexOf("base64") >= 0
      ? atob(splitDataURI[1])
      : decodeURI(splitDataURI[1]);
  const mimeString = splitDataURI[0].split(":")[1].split(";")[0];

  const ia = new Uint8Array(byteString.length);
  for (let i = 0; i < byteString.length; i++) ia[i] = byteString.charCodeAt(i);

  return new Blob([ia], { type: mimeString });
};

export default function App() {
  const onChange = async (event) => {
    const file = event.target.files[0];
    const image = await resizeFile(file);
    console.log(image);
    const newFile = dataURIToBlob(image);
    const formData = new FormData();
    formData.append("image", newFile);
    const res = await fetch(
      "https://run.mocky.io/v3/c5189845-2a93-49aa-85c7-70bc64e8af90",
      {
        method: "POST",
        body: formData
      }
    );
    const data = await res.text();
    console.log(data);
  };

  return (
    <div className="App">
      <input onChange={onChange} type="file" />
    </div>
  );
}

We added the dataURItoBlob function to convert the base64 string back to a file.

It looks through the byte string created from the base64 string and put it in a Uint8Array.

Then that's put in the Blob constructor to return the file object.

Once we did that, we put that in the FormData constructor.

Then we upload it with the fetch function.

Conclusion

We can compress and resize images before uploading it in a React app with the React Image File Resizer package.

Enjoyed this article?

Share it with your network to help others discover it

Continue Learning

Discover more articles on similar topics