coobird / thumbnailator

Thumbnailator - a thumbnail generation library for Java
MIT License
5.08k stars 780 forks source link

Neon sign fade color in jpeg image after resize #182

Open MaxMuhachev opened 2 years ago

MaxMuhachev commented 2 years ago

Expected behavior

Neon sign does not fade color in jpeg image

Actual behavior

The letters on the neon sign are fading color. There is no color fading only if there is a record to the file via png

Steps to reproduce the behavior

Original image: https://disk.yandex.ru/i/LkfddI1emi-xnA (The letters on the neon sign are fading color) Second example: https://disk.yandex.ru/i/EQ9xf88fLVFHUw (flying bullet color fading in centre)

A sign with fading color neon letters: BufferedImage resizedImageBuffer; try { resizedImageBuffer = Thumbnails.of(from) .forceSize(444, 296) .outputQuality(1f) .outputFormat("JPEG") .scalingMode(ScalingMode.PROGRESSIVE_BILINEAR) .alphaInterpolation(AlphaInterpolation.QUALITY) .dithering(Dithering.ENABLE) .antialiasing(Antialiasing.ON) .asBufferedImage(); } catch (IOException ex) { throw new RuntimeException(ex); } ImageIO.write(resizedImageBuffer, "JPEG", to);

A sign without faded color neon letters: BufferedImage resizedImageBuffer; try { resizedImageBuffer = Thumbnails.of(from) .forceSize(width, height) .outputQuality(1f) .outputFormat("png") .scalingMode(ScalingMode.PROGRESSIVE_BILINEAR) .alphaInterpolation(AlphaInterpolation.QUALITY) .dithering(Dithering.ENABLE) .antialiasing(Antialiasing.ON) .asBufferedImage(); } catch (IOException ex) { throw new RuntimeException(ex); } ImageIO.write(resizedImageBuffer, "png", to);

Environment

coobird commented 2 years ago

@MaxMuhachev, have you tried using the toFile method rather than the asBufferedImage?

For example:

Thumbnails.of(from)
    .size(...)
    .toFile(to); // or toOutputStream

I couldn't tell if the "original image" is the actual source or the output from Thumbnailator, but my guess from the fact the issue is with a JPEG image (and not PNG) and when it's saved from a BufferedImage via ImageIO.write, it leads me to believe it's a known issue with the JPEG encoder bundled with Java having issues with certain JPEG files. Thumbnailator's toFile method contains a workaround for such files, so you may have better results with that instead.

Also to note, since you're using asBufferedImage to get a BufferedImage, the outputFormat and outputQuality settings have no effect, since those settings are only used when writing to a file or an OutputStream.

MaxMuhachev commented 2 years ago

@coobird Unfortunately, using the toFile method does not help to solve the problem. Everything remains as I described above.

Only now I use it: Thumbnails.of(from) .forceSize(width, height) .outputQuality(1f) .outputFormat("jpg") .scalingMode(ScalingMode.PROGRESSIVE_BILINEAR) .alphaInterpolation(AlphaInterpolation.QUALITY) .dithering(Dithering.ENABLE) .antialiasing(Antialiasing.ON) .toFile(to);

And it: Thumbnails.of(from) .forceSize(width, height) .outputQuality(1f) .outputFormat("png") .scalingMode(ScalingMode.PROGRESSIVE_BILINEAR) .alphaInterpolation(AlphaInterpolation.QUALITY) .dithering(Dithering.ENABLE) .antialiasing(Antialiasing.ON) .toFile(to);

MaxMuhachev commented 2 years ago

@coobird, please, help

coobird commented 2 years ago

@MaxMuhachev, one possibility is that the JPEG reader that's bundled with Java is having issues properly reading that JPEG image. Have you tried using the TwelveMonkeys ImageIO plugins? The JPEG plugin does a better job handling a wide range of JPEGs than the one bundled with Java.