如何在具有相同或更低DPI的Java中调整图像大小

如何在具有相同或更低DPI的Java中调整图像大小,java,image-resizing,imgscalr,Java,Image Resizing,Imgscalr,我试图在Java中调整jpg图像文件的大小。为此,我使用Scalr。 我有大约16MB的图像,分辨率为6000x4000,分辨率为350 dpi 当我将其调整为4500宽度时,它也将DPI缩小到96 这是我正在使用的代码: Scalr.resize(img, Scalr.Method.ULTRA_QUALITY, 4500, Scalr.OP_ANTIALIAS); 我在没有任何库的情况下进行了尝试,代码如下: private static BufferedImage resi

我试图在Java中调整jpg图像文件的大小。为此,我使用Scalr。 我有大约16MB的图像,分辨率为6000x4000,分辨率为350 dpi

当我将其调整为4500宽度时,它也将DPI缩小到96

这是我正在使用的代码:

    Scalr.resize(img, Scalr.Method.ULTRA_QUALITY, 4500, Scalr.OP_ANTIALIAS);
我在没有任何库的情况下进行了尝试,代码如下:

    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;
}

但结果是一样的。因此,如果可能的话,我如何调整图像的dpi为150左右,如果不可能,我如何调整图像的dpi为350左右。

将dpi存储在图像中意味着您要保存图像。(这在您的问题中并不清楚。)您需要直接在编码器中指定元数据。这是JPEG版本。我发现PNG也是可能的,因为它需要不同的元数据树节点

[编辑]我找到了一种不依赖专有类的方法

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();
}
改编自


PNG版本

在Java中,图像没有“dpi”。事实上,图像除了调色板之外没有其他元数据。@MarkJeronimus所以我怎样才能将图像调整到较低的分辨率,但又不丢失DPI并将其保持在原来的350。我是在c#net中做的,所以我知道这是可能的,只是想知道它在Java中是如何可能的。顺便说一句,看看我改进的质量多线程感谢这一点。我在元素树上遇到错误。我应该为该“元素”导入哪个库?导入中的库