1

I am trying to resize jpg Image files in Java. For this I am using Scalr. I have around 16MB image with 6000x4000 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.

Hemant Sisodia
  • 488
  • 6
  • 23
  • 1
    In Java, images do not have a 'dpi'. In fact, images have no metadata other than possibly palette. – Mark Jeronimus Aug 22 '19 at 07:29
  • @MarkJeronimus So how can I resize the Image to lower resolution but without loosing the DPI and keeping it to original 350. I did this in c# .net so I know this is possible though, just want to know how it is possible in Java. – Hemant Sisodia Aug 22 '19 at 07:33
  • Btw look at my improved-quality multi-threaded [image resizer](https://github.com/MarkJeronimus/ImageUtilities) – Mark Jeronimus Aug 22 '19 at 09:46

2 Answers2

1

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

Mark Jeronimus
  • 9,278
  • 3
  • 37
  • 50
0

this work for me, jpg 72 -> 300

public static void handleDpi(File file, int xDensity, int yDensity) {
        try {
            BufferedImage image = ImageIO.read(file);
            JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(new FileOutputStream(file));
            JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);
            jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
            jpegEncoder.setJPEGEncodeParam(jpegEncodeParam);
            jpegEncodeParam.setQuality(0.75f, false);
            jpegEncodeParam.setXDensity(xDensity);
            jpegEncodeParam.setYDensity(yDensity);
            jpegEncoder.encode(image, jpegEncodeParam);
            image.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 02 '21 at 08:36