【问题标题】:Increasing Resolution and Reducing Size of an Image in Java在 Java 中增加分辨率并减小图像的大小
【发布时间】:2012-12-20 17:59:07
【问题描述】:

当我第一次问这个问题时,我尽可能多地提供了信息,因为我不知道如果他们可以提供解决方案会对某人有所帮助,但从答案来看,我似乎没有明确表达我的观点。

我将原始文本留在底部并缩短它。我希望这能说清楚。

我正在处理从另一个程序返回给我的图像。例如,我可以在 72 DPI 下获得 8x10 的图像,或者在 16x20 下以 72DPI 获得相同的图像。

我正在使用 Java。我想做的是拍摄 16x20 图像并调整其大小。如果可能的话,我只想更改文件,而不是 72DPI 时的 16x20,而是 144DPI 时的 8x10。

我知道它仍然是相同数量的像素,但观众会说图像有多大和 DPI 是多少,并且有些人会打开图像到其全尺寸,所以我宁愿他们将 16x20 视为较小的图像具有较高的分辨率。

我可以在 Java 中做到这一点吗?我会丢失任何数据吗?我该怎么做 - 我可以只更改 png 或 jpg 文件中的元数据吗?

-----(这里的原始问题)-----

我已经看到了一些接近这个的问题,但这有点不同。

我知道你可以 decrease image resolution 使用 Java 中的图像 (also here)。我所做的任何搜索都与降低图像分辨率有关。

我有相反的问题。我正在处理以 72DPI 恢复的图像。优点是我可以增加图片的大小,所以我可以将大小设置为 100%、200%、400% 等等。所有图像都是 72DPI,所以如果我使用 200% 进行缩放,然后在查看器中打开图像并使其大小与 100% 图像相同,我会看到更好的分辨率。

为了清楚起见 - 我从其他人那里获取图像,它可能是从 PDF 或图片生成的,但我给定图像来自另一个程序。无论我做什么,这张图片都是 72DPI。我无法更改它,但我可以将大小指定为 200%,它仍然会返回 72DPI,只是两倍大且更详细。

我不是图形专家,这是我第一次使用图形进行任何编程。输出可以是 jpg 或 png,所以格式并不那么重要。 (如果需要,我可能还可以使用其他格式。)

假设原始图像是一张照片 - 8" x 10",并且 DPI 为 72。如果我要求 200% 缩放,我会得到 72DPI 的 16" x 20" 图像。

我能否在 Java 中将较大的 16" x 20" 72DPI 图像更改为 8" x 10" 的 144DPI 图像而不会丢失数据?换句话说,将 DPI 翻倍,但将尺寸减半?

而且,最重要的是,我可以做到这一点而不会失去决心吗? (我认为可以做到。)

【问题讨论】:

  • 这可能更适合Photography
  • @JimGarrison:我会考虑,但我需要用 Java 来做,这不是摄影问题。它可以作为 Java 程序的一部分来完成吗?

标签: java graphics resolution


【解决方案1】:

不,如果您拍摄 8x10 72dpi 的图像并要求 200% 缩放,您将获得 36 dpi 的 16x20。你不能神奇地提高图像分辨率。

重要的是图像中的像素总数。规定的 DPI 就是特定大小的 DPI。以 72dpi 拍摄 8x10 图像。它有 576x720 像素。如果您放大到 200%,您仍然拥有相同数量的像素,但现在它们将分布在两倍的线性尺寸上,这意味着单个像素会更大。一些软件会尝试通过插值像素来提高分辨率,即通过平均最近的邻居来创建新像素。这可以给人以更高分辨率的印象,但图像不包含更多数据。它始终具有柔化图像的效果,尤其是任何锐利的边缘或线条。

如果您缩小图像的大小而不重新采样,您确实会增加打印或显示的分辨率,但图像会变小。对于相同的图像,将 DPI 增加到 144 会将图像尺寸减小到 4x5。

【讨论】:

  • 不,情况并非如此。我可以请求源图像,并且可以 100% 或 200% 请求它。因此,如果我得到一个 200% 的图像,它 为 72DPI 和 16" x 20"。这就是我得到的。诀窍是,如果我以更大的尺寸拍摄 72DPI,并以更高的分辨率将其缩小到更小的尺寸。
  • 其实,是的,你说得对,就是图像中的像素数。这就是重点的一部分:如果图像是 8 英寸宽,并且我要求 100% 宽,我会得到 8x72 像素(或 576 像素)。如果我要求 200% 宽,我会得到 16x72 像素(或1,152 像素)。我想拍摄 16" 的图像,1,152 像素,将其更改为 8" 并具有相同的像素数。
【解决方案2】:

这很棘手,因为就像在 Java 中一样,您不能只以简单的方式访问某些内容。 Java 不跟踪 DPI,但它确实使用每毫米点数。此外,令人困惑的另一部分是您无法更改图像或 BufferedImage 中的此类信息。只有在通过 ImageWriter 写入 BufferedImage 时才能更改此信息。

我能够做到这一点。正如我所说,我可以指定返回给我的图像的缩放比例。无论缩放级别如何,输出都是 72 DPI。我的目标是 300DPI。我指定了 400% 的缩放级别。因此,在 72 DPI 的 8 英寸宽图像上,返回给我的是 72 DPI 的 32 英寸图像。我所要做的就是指定一个 288 (72 x 4) 的 DPI 来覆盖我正在处理的默认 72 DPI,然后当它被写出时,图像具有相同数量的像素,但被认为是在288 DPI 而不是 72 DPI。

这是一个代码sn-p:

//假设已经有一个ImageWriter iw

ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier =
       ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
    continue;
}

// 设置参数和信息

int DPI = 72 * scaling/100;
double dotsPerMilli = 1.0 * DPI / 10 / 2.54;
double checkDots = 1.0 * 144 / 10 / 2.54;
System.out.println("Dots per inch: " + DPI + ", DotsPerMilli: " + dotsPerMilli + ",
    CheckDots = " + checkDots);
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
horiz.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
vert.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode dim = new IIOMetadataNode("Dimension");
dim.appendChild(horiz);
dim.appendChild(vert);
root.appendChild(dim);
metadata.mergeTree("javax_imageio_1.0", root);

// 从这里开始,使用 ImageOutputStream 写出文件

final ImageOutputStream stream = ImageIO.createImageOutputStream(outFile);
System.out.println("Output file: " + outFile);
try {
    writer.setOutput(ImageIO.createImageOutputStream(outFile));
    writer.write(metadata, new IIOImage(image_to_save, null, metadata),
    writeParam);
} catch (Exception e) {
    System.out.println("Caught exception " + e + " when trying to write out
        file.");
    System.exit(0);
} finally {
    stream.close();
}

【讨论】:

  • 你的例子中的 scaling 是什么?
  • @patricK:那是 7 年前的事了——在这一点上,我什至不确定这是来自哪个项目。如果有帮助的话,我很有可能正在使用来自 Google 地图的图像。
  • 这里应该缩放什么?在这种情况下是 4 吗?还是我想要的任何目标 dpi?
猜你喜欢
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
相关资源
最近更新 更多