From 1461f33f9f7a731cf19e584a01b899a86206c106 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 13 Feb 2019 10:04:57 -0700 Subject: [PATCH] [VIVO-1674] Improve quality of thumbnails created (#112) * Explicitly set image quality and interpolation method * Use twelvemonkeys plugin for thumbnail creation Resolves: https://jira.duraspace.org/browse/VIVO-1674 --- .../imageio/IIOImageProcessor.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/imageprocessor/imageio/IIOImageProcessor.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/imageprocessor/imageio/IIOImageProcessor.java index 5e0ea8ec3..455a3f601 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/imageprocessor/imageio/IIOImageProcessor.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/imageprocessor/imageio/IIOImageProcessor.java @@ -9,16 +9,20 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.imageio.ImageIO; +import javax.imageio.IIOImage; +import javax.imageio.ImageWriter; +import javax.imageio.ImageWriteParam; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.MemoryCacheImageInputStream; -import java.awt.geom.AffineTransform; -import java.awt.image.AffineTransformOp; +import javax.imageio.stream.MemoryCacheImageOutputStream; import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; import java.awt.image.ColorConvertOp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import com.twelvemonkeys.image.ResampleOp; /** * Crop the main image as specified, and scale it to the correct size for a @@ -147,10 +151,10 @@ public class IIOImageProcessor implements ImageProcessor { } private BufferedImage scaleImage(BufferedImage image, float scaleFactor) { - AffineTransform transform = AffineTransform.getScaleInstance( - scaleFactor, scaleFactor); - AffineTransformOp atoOp = new AffineTransformOp(transform, null); - return atoOp.filter(image, null); + int newX = (int) (image.getWidth() * scaleFactor); + int newY = (int) (image.getHeight() * scaleFactor); + BufferedImageOp resampler = new ResampleOp(newX, newY, ResampleOp.FILTER_LANCZOS); + return resampler.filter(image, null); } private CropRectangle adjustCropRectangleToScaledImage(CropRectangle crop, @@ -167,8 +171,14 @@ public class IIOImageProcessor implements ImageProcessor { } private byte[] encodeAsJpeg(BufferedImage image) throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - ImageIO.write(image, "JPG", bytes); + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next(); + ImageWriteParam param = writer.getDefaultWriteParam(); + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(0.8f); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + writer.setOutput(new MemoryCacheImageOutputStream(bytes)); + writer.write(null, new IIOImage(image,null,null),param); + writer.dispose(); return bytes.toByteArray(); } }