在Java中增加分辨率和缩小图像的大小 [英] Increasing Resolution and Reducing Size of an Image in Java

查看:204
本文介绍了在Java中增加分辨率和缩小图像的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我第一次问到这个问题时,我尽可能地提供了尽可能多的信息,因为如果他们能够给出解决方案,我永远不知道什么能够帮助到某个人,但是从答案来看,我似乎没有明确表明我的观点。 / p>

我将原文放在底部并缩短。我希望能够说清楚。



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

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



我知道它仍然是相同的像素数,但观众会说图像有多大,DPI是什么,还有一些图像是全尺寸的,所以我宁愿他们把16x20视为更高分辨率的小图像。



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



-----(下面的原始问题)-----



我已经看到一些与此相近的问题,但这有些不同。



我知道您可以使用Java中的图像降低图像分辨率也在这里)。我所做的任何搜索一直关注降低图像的分辨率。



我有相反的问题。我正在处理一个我以72DPI回归的图像。好处是我可以增加图片的尺寸,所以我可以使尺寸达到100%,200%,400%等等。所有图像都在72DPI,所以如果我使用200%的缩放比例,然后在查看器中打开图像,并使其与100%图像大小相同,我看到更好的分辨率。



为了清晰起见 - 我从其他人那里获取图像,可以从PDF或图片生成图像,但是我从另一个程序获取图像。无论我做什么,这张图片都是72DPI。我无法改变这种情况,但我可以将尺寸指定为200%,并且仍然可以恢复到72DPI,只是尺寸的两倍和更多细节。



没有图形专家,这是我第一次完成任何使用图形的编程。输出可能是jpg或png,所以格式不是那么重要。 (如果需要,我大概也可以使用其他格式。)



假设原始图像是一张8英寸x 10英寸的照片,并且位于72 DPI。如果我要求200%的缩放比例,我会得到一张72英寸x 16英寸x 20英寸的图像。



我可以在Java内将16x 20 72DPI图像到8x 10的144DPI图像,而不会丢失数据?换句话说,DPI翻了一番,但是把尺寸减半了吗?

最重要的是,我可以在不损失分辨率的情况下做到这一点吗? (我认为这是可以做到的。)

解决方案

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



我能够做到这一点。正如我所说,我可以在返回给我的图像上指定缩放比例。无论缩放级别如何,输出都是72 DPI。我的目标是300DPI。我指定了400%的缩放级别。因此,在72英寸宽的8英寸宽的图像上,返回给我72英寸32英寸的图像。我所要做的只是指定DPI为288(72 x 4)来覆盖我正在处理的默认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(每英寸点数:+ DPI +,DotsPerMilli:+ dotsPerMilli +,
CheckDots =+ checkDots);
IIOMetadataNode root = new IIOMetadataNode(javax_imageio_1.0);
IIOMetadataNode horiz = new IIOMetadataNode(Horizo​​ntalPixelSize);
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(元数据,新的IIOImage(image_to_save,null,元数据),
writeParam);
} catch(Exception e){
System.out.println(Caught exception+ e +当试图写出
文件时。);
System.exit(0);
} finally {
stream.close();
}


When I first asked this, I included as much information as I could, since I never know what will help someone if they can give m a solution, but from the answers, it seems I didn't make my point clear.

I'm leaving the original text at the bottom and shortening this. I hope that makes it clear.

I am working with images returned to me from another program. I can get an image that's, for example, 8x10 at 72 DPI or the same image at 16x20, also at 72DPI.

I'm working in Java. What I'd like to do is take the 16x20 image and resize it. If possible, I'd like to just change the file so instead of being 16x20 at 72DPI, it's 8x10 at 144DPI.

I know that it's still the same number of pixels, but viewers will say how big an image is and what the DPI is and also some open an image to its full size, so I'd rather them treat the 16x20 as a smaller image with a higher resolution.

Can I do that in Java? Will I lose any data? How would I do it - can I just change the metadata in the png or jpg file?

-----(original question below here)-----

I've seen a few questions that come close to this, but this is a little different.

I know you can decrease image resolution with an image in Java (also here). Any searches I've done have been concerned with decreasing the resolution of an image.

I have the opposite problem. I'm working with an image that I'm getting back in 72DPI. The advantage is I can increase the size of the picture, so I could make the size 100%, 200%, 400% and so on. All images are at 72DPI, so if I use 200% for the zoom, then open the image in a viewer and make it the same size as the 100% image, I am seeing a better resolution.

For clarity - I am getting an image from someone else, it could be generate from a PDF or picture, but I am given the image from another program. No matter what I do, this image is at 72DPI. I can't change that, but I can specify the size at 200% and it still comes back at 72DPI, just twice as big and with more detail.

I'm no graphics expert and this is the first time I've done any programming that uses graphics. The output could be jpg or png, so the format isn't that important. (I could probably also use other formats if needed.)

Let's say the original image is a photo - 8" x 10", and at 72 DPI. If I ask for a 200% zoom, I get a 16" x 20" image at 72DPI.

Can I, within Java, change that larger 16" x 20" 72DPI image to a 144DPI image that's 8" x 10" without losing data? In other words, double the DPI, but cut the size in half?

And, most importantly, can I do it without losing resolution? (I would think that can be done.)

解决方案

This is tricky because, like so much in Java, you can't just access something in a simple way. Java does not keep track of DPI, but it does use dots per millimeter. Also, another part that is confusing is that you cannot change this kind of information in an image, or in a BufferedImage. You can only change this information when you are writing a BufferedImage out through an ImageWriter.

I was able to do this. As I said, I could specify the zoom on the image that was returned to me. No matter what zoom level, the output was 72 DPI. My goal was 300DPI. I specified a zoom level of 400%. So, on an 8" wide image of 72 DPI, that returned to me a 32" image of 72 DPI. All I had to do was specify a DPI of 288 (72 x 4) to override the default 72 DPI I was dealing with and then when it was written out, the image had the same number of pixels, but was considered to be done at 288 DPI rather than 72 DPI.

Here's a code snippet:

//Assumed there's already an 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;
}

// Set Parameters and info

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

// From here, just write out file using an 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();
}

这篇关于在Java中增加分辨率和缩小图像的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆