为什么 Java ImageIO 会使 JPEG 颜色变平

发布于 2024-08-01 23:29:16 字数 882 浏览 3 评论 0原文

当我阅读某些 JPG 文件时,颜色会变得扁平。 这是一个简单的示例,读取 jpg 并将相同的图像写入另一个文件。

import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class JPegReadTest {
    public static void main(String[] args) {
        if (args.length == 2) {
            try {
                BufferedImage src = ImageIO.read(new File(args[0]));
                ImageIO.write(src, "jpg", new File(args[1]));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.err.println("Usage: java JPegReadTest src dest");
        }
    }
}

如果您尝试使用例如 http://www.flickr.com/photos /visualpanic/233508614/sizes/l/ ,目标图像的颜色与源文件不同。 这是为什么? 如何修复它?

还尝试将图像保存为 png,但其中的颜色也很平淡(因此假设颜色信息未正确读取)。

When I read certain JPG files, colors are flattened. Here is a simple example that reads a jpg and just writes the same image to another file.

import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class JPegReadTest {
    public static void main(String[] args) {
        if (args.length == 2) {
            try {
                BufferedImage src = ImageIO.read(new File(args[0]));
                ImageIO.write(src, "jpg", new File(args[1]));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.err.println("Usage: java JPegReadTest src dest");
        }
    }
}

If you try this with for example http://www.flickr.com/photos/visualpanic/233508614/sizes/l/ , the colors of the destination image differ from the source file. Why is that? How to fix it?

Also tried saving the image as png, but the colors are bland in it too (so assuming color info is not read properly).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你的背包 2024-08-08 23:29:16

也许您的源图像具有指定的颜色配置文件,其色域比 sRGB(如 Adob​​e RGB)更宽,并且您的加载/保存周期没有保留颜色空间信息? 如果没有颜色配置文件,您的观看者将采用 sRGB,而压缩的色域将使一切看起来“乏味”。 如果您有 exiftool,

exiftool -ProfileDescription filename.jpg

这是验证源图像和输出图像的颜色配置文件的快速方法。

Perhaps your source image has an assigned color profile with a gamut wider than sRGB (like Adobe RGB), and your load/save cycle isn't preserving the colorspace information? With no color profile, your viewer will assume sRGB, and the compressed gamut will make everything look "blah". If you have exiftool,

exiftool -ProfileDescription filename.jpg

is a quick way to verify the color profiles on your source and output images.

人间☆小暴躁 2024-08-08 23:29:16

jpeg 是一种有损格式。 读入时,java 将其存储为原始格式,就像 BMP 一样。 然后它会再次被写出,导致数据丢失。 此外,与使用 GIMP 等工具时相比,对质量没有太多控制。

也许可以考虑使用其他 API,例如 Image Magick 来更好地控制质量。

jpeg is a lossy format. When read in, java stores it as a raw format much like an BMP. Then it's being written out again causing data loss. Also, there isnt much control over the quality like when using something like GIMP.

Maybe look into using other APIs like Image Magick to give you more control over quality.

儭儭莪哋寶赑 2024-08-08 23:29:16

这是在 ImageIO 接口上扩展的源代码链接 - 您可以在写入图像时更改质量和压缩参数......
http ://www.universalwebservices.net/web-programming-resources/java/adjust-jpeg-image-compression-quality-when- saving-images-in-java

Here is a link with source code that expands on the ImageIO interface - you can change the quality and compression parameters when writing an image....
http://www.universalwebservices.net/web-programming-resources/java/adjust-jpeg-image-compression-quality-when-saving-images-in-java

何处潇湘 2024-08-08 23:29:16

JPEG 是一个 有损 格式。

这意味着,如果您打开一个文件并再次保存它,您将丢失一些信息,除非您采取非常具体的步骤来不丢失任何信息(在这种情况下,可能的操作非常有限)。

此外,ImageIO.write() 可能会使用一些默认质量设置来保存 JPEG 文件,这些设置可能低于原始质量,这会导致额外的质量损失。

尝试保存为 PNG 文件,您会发现它看起来与源文件相同。

JPEG is a lossy format.

That means that if you open a file and save it again you will lose some information unless you take very specific steps not to lose any (in which case the possible manipulations are very restricted).

Additionally ImageIO.write() probably uses some default quality settings for saving JPEG files, which might be lower than the original, which would lead to an additional loss of quality.

Try saving to a PNG file and you'll see that it will look the same as the source.

紫﹏色ふ单纯 2024-08-08 23:29:16

这可能有几个原因。

  1. JPEG 颜色数据通常存储为 YCrCb 而不是 RGB,尽管转换通常不会引起注意。
  2. JPEG 通常具有嵌入的颜色配置文件,但许多应用程序不理解这一点并简单地忽略它(在这种情况下,您的输出文件可能会丢失颜色配置文件)。
  3. Java 破坏伽玛值后,伽玛值可能会被重置或丢失。

我实际上并没有尝试你的例子......你能发布之前和之后的文件吗? 如果无法实际检查结果文件,则很难判断这些额外数据是否存在。

编辑:是的,很明显,您的原始图像和转换后的图像具有不同的颜色配置文件。 Java 去掉了原始的颜色配置文件并使用通用的 sRGB 代替。 它们在使用 Firefox 和各种程序的 Windows 上看起来与我们相同,因为这些程序在渲染时不使用颜色配置文件。 然而,在您的 Mac 上,Mac 实际上支持这些颜色配置文件(提示关于 Mac 图形等的争论),因此它们的渲染方式有所不同。 我手边没有 Mac,但我怀疑如果您在任何平台上的 Photoshop 中打开文件,您都会看到差异。

It could be several reasons.

  1. JPEG color data is often stored as YCrCb instead of RGB, although conversions should be mostly unnoticeable.
  2. JPEG often has an embedded color profile, but many applications do not understand this and simply ignore it (in which case, your output file might be missing the color profile).
  3. Gamma value could be reset or missing after Java mangles it.

I didn't actually try your example... could you please post both before and after files? Without actually being able to examine the result file, it's hard to tell if this extra data is there or not.

Edit: Yeah, it's clear that your original and converted images have different color profiles. Java stripped out the original's color profile and used generic sRGB instead. They look the same to us on Windows with Firefox and assorted programs because these programs don't use the color profile when renderer. However, on your Mac, Mac actually supports these color profiles (cue debate over Macs for graphics, etc.) and so they render differently. I don't have a Mac handy, but I suspect that if you open the files in Photoshop on any platform, you'll see the difference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文