coobird / thumbnailator

Thumbnailator - a thumbnail generation library for Java
MIT License
5.17k stars 789 forks source link

Using `BufferedImage` decreases the quality of the output image #76

Closed GoogleCodeExporter closed 7 years ago

GoogleCodeExporter commented 9 years ago
Hi,

First of all, i want to thank you for this beautiful library.

My goal through using Thumbnailator is to create a watermarked resized images. 

I have looked at the examples and some of answers of stackoverflow to create a 
simple program that fulfill my goal.

My problem is that the quality is decreasing when i use BufferedImage as a 
temporary placeholder for the resized image and writing it to disk. Here is the 
code producing the bad quality image.

        BufferedImage resizedImage =Thumbnails.of(new File("/Library/WebServer/Documents/assets/photo/69/photo.png"))
                .outputFormat("jpg")
                .outputQuality(1.0)
                .size(500, 350)
                .asBufferedImage();

        if (caption != null) {
            Caption filter =  new Caption(caption, font, color, 0.7f, position, margin);
            resizedImage = filter.apply(resizedImage);
        }
         ImageIO.write(resizedImage, "jpg", new File("/Users/dev/Desktop/pizza.jpg"));

When using Thumbnailator like the code below, everything goes fine:

        Thumbnails.of(new File("/Library/WebServer/Documents/assets/photo/69/photo.png"))
                .outputFormat("jpg")
                .outputQuality(1.0)
                .size(500, 350)
                .toFile(new File("/Users/dev/Desktop/isa.jpg"));

But with the code above i can't create a thumbnail. 

I have seen in the examples that i can create a watermark via the    watermark 
method but i didn't understand how to make a watermark file?

May be i'm not doing the right way in the first example. I have how do 

I'm using jdk 1.8 on Mac Os X 10.10.

Attached the orginal image :bmw_PNG1710.png the result without BufferedImage 
withoutBufferedImage.jpg and using it using_bufferedImage.jpg

Thanks in advance,

Here is 

Original issue reported on code.google.com by devcar1...@gmail.com on 18 May 2015 at 10:06

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you for taking time to write about the issue. I'm glad to hear that you 
found Thumbnailator useful and sorry for the delay in responding.

The issue that you encountered with the `BufferedImage` being saved using 
`ImageIO.write` ending up with colors being distorted is an known issue with 
the JPEG encoder included with the Java runtime. You do not encounter this 
problem when writing the JPEG using the `toFile` method is because 
Thumbnailator implements a workaround to prevent this problem from occurring.

Looking at your code for the first example, it appears that you want to add a 
caption when the caption is given. This is a use case that Thumbnailator does 
not support really well.

The "safest" way to implement what you want to achieve would be to use a code 
block like the following:

  if (caption != null) {
    Thumbnails.of("path/to/file")
      .size(100, 100)
      .outputFormat("jpg")
      .outputQuality(1.0)
      .addFilter(new Caption(caption, font, color, 0.7f, position, margin))
      .toFile("path/to/thumbnail"); 

  } else {
    Thumbnails.of("path/to/file")
      .size(100, 100)
      .outputFormat("jpg")
      .outputQuality(1.0)
      .toFile("path/to/thumbnail"); 
  }

Regarding adding a watermark, you'll first need to load a image to a 
`BufferedImage` first, then use one of the `watermark` methods to specify what 
kind of watermark you want. The simplest way would be:

    BufferedImage wm = ImageIO.read(new File("path/to/watermark");

    Thumbnails.of("path/to/file")
      .size(100, 100)
      .watermark(wm)
      .outputFormat("jpg")
      .outputQuality(1.0)
      .toFile("path/to/thumbnail"); 

The above code will place a completely opaque (non-transparent) watermark in 
the center of the final image.

A more involved method will allow you to set the position and opacity:

    BufferedImage wm = ImageIO.read(new File("path/to/watermark");

    Thumbnails.of("path/to/file")
      .size(100, 100)
      .watermark(Positions.BOTTOM_RIGHT, wm, 0.5f)
      .outputFormat("jpg")
      .outputQuality(1.0)
      .toFile("path/to/thumbnail"); 

The above will place the watermark at the bottom right-hand corner with a 
opacity of 50%.

I hope those examples are what you are looking for.

Original comment by coobird...@gmail.com on 16 Jun 2015 at 4:38

GoogleCodeExporter commented 9 years ago
Thank you for answer it's very helpful

Original comment by devcar1...@gmail.com on 17 Jun 2015 at 3:13

coobird commented 7 years ago

Closing issue, as question has been answered, and no activity for almost 2 years.