Getting low quality thumbnail from a high quality image in Java
I have tried the below code to generate the high quality thumbnail image but got the thumb nail blurred and not that much clarity.
BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = thumbImage.createGraphics();
graphics2D.setBackground(Color.WHITE);
graphics2D.setPaint(Color.WHITE);
graphics2D.fillRect(0, 0, thumbWidth, thumbHeight);
graphics2D.setComposite(AlphaComposite.Src);
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_开发者_开发问答RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);
graphics2D.dispose();
File file = new File(thumbnailFile);
if (javax.imageio.ImageIO.write(thumbImage, "JPG", file))
return file;
}
The original image is a high quality image. Why am I getting the thumbnail image distorted and low in quality?
There are two possibilities from looking at the code:
The original image is very large, and the thumbnail is very small, resulting in image quality being degraded by the simple bilinear interpolation.
The compression artifacts resulting from the JPEG encoding is degrading the quality of the thumbnail.
Using a simple bilinear interpolation can be adequate if the original image and the thumbnail doesn't differ in size by a whole lot, for example, going from a 200x200 to 100x100.
However, when it comes to resizing images that are large (such as 1600x1200) to a thumbnail size image, bilinear interpolation (and bicubic interpolation, for that matter), so alternative techniques such as multi-step resizing should be used.
The article The Perils of Image.getScaledInstance() by Chris Campbell goes into more details about how and why downscaling large images can lead to degradation of image quality.
The book Filthy Rich Clients by Chet Haase and Romain Guy also goes into some details about creating high-quality thumbnails.
I maintain a thumbnail generation library called Thumbnailator, which uses techniques such as multi-step resizing to create high-quality thumbnails with an easy-to-use API.
For example, your example code could be written using Thumbnailator like this:
Thumbnails.of(image)
.size(thumbWidth, thumbHeight)
.outputFormat("JPG")
.toFile(file);
It's also possible to specify the compression quality settings if compression artifacts are causing image quality degradation:
Thumbnails.of(image)
.size(thumbWidth, thumbHeight)
.outputFormat("JPG")
.outoutQuality(0.9)
.toFile(file);
Thumbnails4j (I'm a maintainer, but it's owned by Elastic) is a java library that can be used to create thumbnails from image files, as well as from other file types.
File input = new File("/path/to/my_file.jpeg");
Thumbnailer thumbnailer = new ImageThumbnailer("png"); // or "jpg", whichever output format you want
List<Dimensions> outputDimensions = Collections.singletonList(new Dimensions(100, 100));
BufferedImage output = thumbnailer.getThumbnails(input, outputDimensions).get(0);
One of the approaches it takes is to iteratively resize the image, instead of jumping straight to the desired size, as this helps to preserve image quality. But this library allows you to avoid having to worry about the details of the image processing algorithm.
精彩评论