coobird / thumbnailator

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

Thumbnail not properly generating from PNG images #200

Closed gotson closed 1 year ago

gotson commented 1 year ago

Expected behavior

Please describe what you are expecting the library to perform.

The thumbnail should have been created without distortion.

Actual behavior

Please describe the actual behavior you are experiencing, including stack trace and other information which would help diagnose the issue.

Thumbnails are distorted Sample 1: image has a blue tint vs Sample 3 which is the same image converted to JPEG Sample 2: Image has missing detail (PNG4 with missing color channels) 191152732-15d38ce2-30c8-4500-9c2d-76555ee3d403

Sample 1 thumbnail in JPG: Sample_1

Sample 2 thumbnail in JPEG: Sample_2

Steps to reproduce the behavior

Please enter step-by-step instructions for reproducing the actual behavior. Including code can be helpful in diagnosing issue, but please keep the code to a minimal that will reproduce the behavior.

A user of my application ran into an issue with some png images when generating the thumbnails

The code we use is very simple:

Thumbnails.of(imageBytes.inputStream())
        .size(300, 300)
        .outputFormat("jpeg)
        .toOutputStream(os)

Original sample in zip files for your convenience: Sample_1.zip Sample_2.zip

Issue reported here: https://github.com/gotson/komga/issues/976

Environment

Please provide vendor and version information for the Operating System, JDK, and Thumbnailator. Please feel free to add any other information which may be pertinent.

coobird commented 1 year ago

@gotson, Thumbnailator uses the BufferedImage image type as the original when resizing the image. If the original image has a reduced number of colors, during the resize process, it will use reduced number of colors. As a result, we can end up with suboptimal results, including the issues you've seen.

One way to avoid this is to force Thumbnailator to use a different image type internally when processing by using .imageType(BufferedImage.TYPE_INT_ARGB). This also means that the resulting image will use that image type, which in this case is 8-bits per channel (with alpha, which is ignored when writing to JPEGs.)

Hence, if you modify your code to:

Thumbnails.of(imageBytes.inputStream())
        .size(300, 300)
        .imageType(BufferedImage.TYPE_INT_ARGB)
        .outputFormat("jpeg")
        .toOutputStream(os)

then, the problem with odd colors and poor resizing should be resolved.

gotson commented 1 year ago

Thanks a lot @coobird , it solves my problem indeed!