当我第一次提出这个问题时,我尽可能多地提供了信息,因为我从来不知道如果他们可以提供解决方案会对他们有什么帮助,但从答案来看,似乎我没有明白我的观点。 / p>
我将原始文字留在底部并缩短了这一点。我希望这说清楚。
我正在处理从另一个程序返回给我的图像。我可以得到一个图像,例如,72 x DPI时的8x10或16x20时的相同图像,也是72DPI。
我在Java工作。我想做的是拍摄16x20图像并调整大小。如果可能的话,我只想更改文件,而不是在72DPI时为16x20,在144DPI时为8x10。
我知道它仍然是相同数量的像素,但是观众会说出图像的大小和DPI是多少,还有一些是打开一个完整尺寸的图像,所以我宁愿他们将16x20视为一个分辨率更高的小图像。
我可以用Java做到吗?我会丢失任何数据吗?我该怎么做 - 我可以只更改png或jpg文件中的元数据吗?
-----(这里的原始问题)-----
我已经看到了一些接近这个的问题,但这有点不同。
我知道您可以使用Java(decrease image resolution)中的图像also here。我所做的任何搜索都关注降低图像的分辨率。
我有相反的问题。我正在处理一张我正在72DPI中恢复的图像。优点是我可以增加图片的大小,所以我可以使尺寸100%,200%,400%等。所有图像均为72DPI,因此如果我使用200%进行缩放,则在查看器中打开图像并使其与100%图像的尺寸相同,我看到更好的分辨率。
为了清楚起见 - 我从别人那里得到一张图片,它可以从PDF或图片中生成,但我给予来自另一个程序的图像。无论我做什么,这张图片都是72DPI。我无法改变这一点,但我可以指定200%的尺寸,它仍然可以恢复到72DPI,只有两倍大,而且细节更多。
我不是图形专家,这是我第一次使用图形进行任何编程。输出可能是jpg或png,因此格式并不重要。 (如果需要,我也可以使用其他格式。)
假设原始图像是一张照片 - 8“x 10”,并且是72 DPI。如果我要求200%变焦,我会在72DPI时获得16“x 20”的图像。
我可以在Java中将更大的16“x 20”72DPI图像更改为8“x 10”的144DPI图像而不会丢失数据吗?换句话说,DPI增加一倍,但将尺寸缩小了一半?
而且,最重要的是,我可以在不失去解决方案的情况下这样做吗? (我认为可以做到。)
答案 0 :(得分:4)
不,如果您拍摄8x10 72dpi图像并要求200%变焦,则会在36 dpi时获得16x20。你无法神奇地提高图像分辨率。
重要的是图像中的像素总数。规定的DPI正是DPI将达到特定规模的水平。以72dpi拍摄8x10图像。它有576x720像素。如果缩放到200%,你仍然拥有相同数量的像素,但现在它们将分布在线性尺寸的两倍以上,这意味着单个像素将更大。一些软件将试图通过内插像素来增加分辨率,即通过平均最近邻居来创建新像素。这可以给人以更高分辨率的印象,但图像不再包含任何数据。它总是具有软化图像的效果,尤其是任何锐利的边缘或线条。
如果减少图像的大小而不重新采样,则会增加打印或显示的分辨率,但图像会变小。对于同一图像,将DPI增加到144会将图像尺寸减小到4x5。
答案 1 :(得分:1)
这很棘手,因为像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。
以下是代码段:
//假设已经有一个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();
}