I am trying to resize jpg Image files in Java. For this I am using Scalr. I have around 16MB image with 6000×4000 Resolution and 350 dpi.
When I resize it to 4500 width, it downscales the DPI also to 96.
This is the code I am using:
Scalr.resize(img, Scalr.Method.ULTRA_QUALITY, 4500, Scalr.OP_ANTIALIAS);
I tried it without any library with the code as:
private static BufferedImage resizeImageWithHint(BufferedImage originalImage, int type, int IMG_WIDTH, int IMG_HEIGHT) { BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); Graphics2D g = resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null); g.dispose(); g.setComposite(AlphaComposite.Src); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); return resizedImage; }
But the result was same. So how can I resize the images with dpi around 150 if possible and same 350 dpi if not possible.
Advertisement
Answer
To store the DPI in an image implies that you want to save the image. (this wasn’t clear in your question.) You need to specify the metadata directly in the encoder. Here’s the JPEG version. I saw it’s possible to PNG too it needs different metadata tree nodes.
[Edit] I found a way that doesn’t rely on proprietary classes.
import org.w3c.dom.Element; ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next(); ImageWriteParam param = writer.getDefaultWriteParam(); param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); param.setCompressionQuality(0.95f); IIOMetadata metadata = writer.getDefaultImageMetadata(ImageTypeSpecifier.createFromRenderedImage(image), param); Element tree = (Element)metadata.getAsTree("javax_imageio_jpeg_image_1.0"); Element jfif = (Element)tree.getElementsByTagName("app0JFIF").item(0); jfif.setAttribute("Xdensity", Integer.toString(350)); jfif.setAttribute("Ydensity", Integer.toString(350)); jfif.setAttribute("resUnits", "1"); // In pixels-per-inch units metadata.mergeTree("javax_imageio_jpeg_image_1.0", tree); try (FileImageOutputStream output = new FileImageOutputStream(new File(filename))) { writer.setOutput(output); IIOImage iioImage = new IIOImage(image, null, metadata); writer.write(metadata, iioImage, param); writer.dispose(); }
Adapted from source
PNG version here