12

In my reactJs project, I need to resize image before uploading it.

I am using react-image-file-resizer library which has a simple example but not working for me.

I have tried this but its shows me blank result. What am I doing wrong?

var imageURI = '';
const resizedImg = await Resizer.imageFileResizer(
  fileList.fileList[0].originFileObj,
  300,
  300,
  'JPEG',
  100,
  0,
  uri  => {
    imageURI = uri 
    console.log(uri )  // this show the correct result I want but outside of this function
  },
  'blob'
);
console.log(resizedImg)
console.log(imageURI)

// upload new image
...uploading image here.. 

If I do imgRef.put(uri); inside URI function then image upload works. but I need to do that outside of that function.

how to get result in imageURI variable and reuse it later ?

Lilith River
  • 16,204
  • 2
  • 44
  • 76
newdeveloper
  • 1,401
  • 3
  • 17
  • 43
  • In the `uri` function you can set the value to state? – Jon B May 11 '20 at 23:11
  • I can but it wont update state right away I need that URI right after converting it. – newdeveloper May 11 '20 at 23:19
  • please check my question, all you have to do is use the putString() function. https://stackoverflow.com/questions/72451963/how-to-resize-image-before-uploading-to-firebase-storage-in-reactjs – motionless570 Jun 03 '22 at 00:06

4 Answers4

13

First, wrap this resizer:

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

And then use it in your async function:

const onChange = async (event) => {
  const file = event.target.files[0];
  const image = await resizeFile(file);
  console.log(image);
}     
Lumpenstein
  • 1,250
  • 1
  • 10
  • 27
Onur Z.
  • 154
  • 1
  • 4
  • 1
    Chose this answer over the accepted answer since this package is smaller than compress.js and it was stupidly simple :) – Android May 09 '22 at 22:15
9

Ok I figured it out using compres.js library.

  async function resizeImageFn(file) {

    const resizedImage = await compress.compress([file], {
      size: 2, // the max size in MB, defaults to 2MB
      quality: 1, // the quality of the image, max is 1,
      maxWidth: 300, // the max width of the output image, defaults to 1920px
      maxHeight: 300, // the max height of the output image, defaults to 1920px
      resize: true // defaults to true, set false if you do not want to resize the image width and height
    })
    const img = resizedImage[0];
    const base64str = img.data
    const imgExt = img.ext
    const resizedFiile = Compress.convertBase64ToFile(base64str, imgExt)
    return resizedFiile;
  }

it return a file to be uploaded to server.

newdeveloper
  • 1,401
  • 3
  • 17
  • 43
2

Image resize in the browser should be pain-free, but it is not. You can use a package, but they are often poorly-written and poorly maintained.

For that reason, I wrote my own code using several Javascript APIs: FileReader, Image, canvas, and context. However, this code produces resizes with some pixelation. If you want even higher quality resizes, I would recommend the Pica package, which uses web workers.

Javascript

const uploadImage = (event) => {
  const [ imageFile ] = event.target.files;
  const { type: mimeType } = imageFile;

  const fileReader = new FileReader();
  fileReader.readAsDataURL(imageFile);
  fileReader.onload = (fileReaderEvent) => {

    const imageAsBase64 = fileReaderEvent.target.result;
    const image = document.createElement("img");
    image.src = imageAsBase64;

    const imageResizeWidth = 100;
    // if (image.width <= imageResizeWidth) {
    //  return;
    // }

    const canvas = document.createElement('canvas');
    canvas.width = imageResizeWidth;
    canvas.height = ~~(image.height * (imageResizeWidth / image.width));
    const context = canvas.getContext('2d', { alpha: false });
    // if (!context) {
    //  return;
    // }
    context.drawImage(image, 0, 0, canvas.width, canvas.height);

    // const resizedImageBinary = canvas.toBlob();
    const resizedImageAsBase64 = canvas.toDataURL(mimeType);
  };
};

HTML

<form>
  <input type="file" accept="image/jpeg"
    onchange="uploadImage()"/>
</form>
tim-montague
  • 16,217
  • 5
  • 62
  • 51
1

The library which you are using will not resize the image for file upload.

It returns of new image's base64 URI or Blob. The URI can be used as the source of an component.

To resize the image: You can refer to the script here

or a working code sample demo here

Ayushya
  • 1,862
  • 1
  • 10
  • 15
  • If I use that blob to upload (inside URI function) it works. so I need that converted value outside of that function. – newdeveloper May 11 '20 at 23:21
  • You're wrong about this package/library. What you said is not correct, it can resize the image, and it can upload the resized image. Here's my StackOverflow question and answer to the same or similar problem using firebase storage. https://stackoverflow.com/questions/72451963/how-to-resize-image-before-uploading-to-firebase-storage-in-reactjs – motionless570 Jun 03 '22 at 00:04