onurzorluer / react-image-file-resizer

Resize Local Images with React 🌄 🌅
MIT License
317 stars 41 forks source link

Multiple problems with quality param #30

Open zehawki opened 4 years ago

zehawki commented 4 years ago

The quality parameter seems to have no predictable pattern to its behavior.

Looking at the description, one is led to believe that setting to 100 will bypass compression, and no compression will be applied for PNG images. To test this, I tried various experiments with the following settings:

A. maxWidth = 800 B. maxHeight = 1000 C. quality = 90, and compressFormat is same as source image

  1. png image of 512x512, size 9.6 KB => results in 18.6 KB, with no resize. Why did the file size double?
  2. jpeg image of 582x864, size 62KB => results in 94.5KB, with no resize. Why did the file size increase?

A. maxWidth = 800 B. maxHeight = 1000 C. quality = 100, and compressFormat is same as source image

  1. png image of 800x800, size 67 KB => results in 170 KB, with no resize. Why did the file size double?
  2. jpeg image of 862x282, size 31KB => results in 73 KB, with resize to 800px. Why did the file size more than double?
tiavina-mika commented 2 years ago

I'm facing the same problem, So is there any explanation or solution?

thany commented 2 years ago

Part of the explanation is for PNG. According to the documentation on toDataURL, the second parameter is ignored for lossless encoding, such as when creating PNG. There appears to be no way to control the compression rate.

It only applies to lossy formats like JPEG and WebP. Which also means that lossless WebP will become lossy after resaving them to WebP.

The reason JPEG becomes bigger, might be in their very nature: re-encoding JPEG means the existing JPEG artefacts are now part of the "original" pixels that needs to go through encoding, which effectively means you'll be getting double JPEG artefacts. Re-encoding a JPEG as another JPEG is never a great idea, unless you're significantly reducing its dimensions.

I suppose resizing images through the browser is just as limited as it is. The only way around this, is to go full serverside. Or I suppose include a full custom library like Sharp on the clientside, which I would not recommend for regular websites, only for locally installed webapps (such as React Native, or Electron).