繁体   English   中英

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

[英]How to resize Image in Java with same or lower DPI

我正在尝试在 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;
}

但结果是一样的。 那么,如果可能的话,我怎样才能用 150 左右的 dpi 调整图像大小,如果不可能的话,我该如何调整 350 dpi 的图像大小。

将 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 版本在这里

这对我有用,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();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM