【问题标题】:ImageIO writes teal where black expectedImageIO 在黑色预期的地方写入蓝绿色
【发布时间】:2017-10-09 16:33:16
【问题描述】:

我写了以下简单的代码来将应该是一个小的全黑图像写入磁盘:

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

public class ImageWriteTest {
    public static void main(String[] args) throws IOException {
        BufferedImage img = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
        final int PIXEL = 0xFF_00_00_00; // Black
        for(int i = 0; i < 10; ++i) {
            for(int j = 0; j < 10; ++j) {
                img.setRGB(i, j, PIXEL);
            }
         }

         ImageIO.write(img, "jpg", new File("/tmp/testImage.jpg"));

         int sample = img.getRGB(0,0);
         System.out.println((sample & 0x00_00_00_FF) + "\t" 
             + ((sample & 0x00_00_FF_00) >>> 8) + "\t" 
             + ((sample & 0x00_FF_00_00) >>> 16) + "\t"
             + ((sample & 0xFF_00_00_00) >>> 24));

         Color color = new Color(sample, true);
         System.out.println(color.getGreen() 
             + "\t" + color.getBlue() 
             + "\t" + color.getRed() 
             + "\t" + color.getAlpha());
    }
}

到终端的输出是两行

0    0    0   255
0    0    0   255

正如我所料。

但是,图像文件看起来是一个小青色方块,而不是一个黑色的小方块,如图所示。

这是在 Windows 10 和 Java 版本 1.8.0_92、Java HotSpot 上运行的。我之前在 Linux 机器上看到了类似的结果。

我发现了两个似乎有些相关的问题,但在这两种情况下,问题似乎都是从外部源将文件读入程序并且有额外的元数据和/或缺少标题。在这种情况下,我以编程方式创建了图像,所以我希望它能够工作。

如果我更改PIXEL = 0x00_00_00_00;,我会得到一个黑色方块。这无疑是一个线索,但我还没有理解。我做错了什么?我该如何解决?

【问题讨论】:

  • @K_7 我喜欢我原来的帖子中可能出现的重复,并解释了为什么我的问题不同。

标签: java image


【解决方案1】:

我不是专家,但这是因为 JPG 不支持 Alpha 通道。将相同的结果更改为PNG,它将如您所料。为此,只需使用

ImageIO.write(img, "png", file);

经过一番搜索,看起来像 ImageIO 中的错误 jpeg image color gets drastically changed after just ImageIO.read() and ImageIO.write()

或者也许根本就不是错误?看看这里: https://stackoverflow.com/a/39478986/1527544 评论说,JPGARGB 读作 CMYK。

【讨论】:

  • 我在等待答案时尝试了 PNG 和 GIF,发现两者在颜色方面都能正常工作 - 尽管在实际应用程序中创建了更大的文件。但是,您链接的问题似乎指向 read 而不是 write 中的错误。我没有做read,尽管它们似乎确实有某种相关性。
  • 是的,那里的评论实际上是://pitfall: in a jpeg file 4 channels will be interpreted as CMYK... this is no good 并且仍然在 write 而不是 read。对另一个答案的评论表明它是 Java 中的一个错误。不过,读写之间肯定是对称错误的,所以我想我被卡住了。知道它在 CMYK 处理它很方便——即使这不是它应该做的! (据我所知,记录的行为是让 API 在幕后进行颜色模型转换。)
  • @Brick 可能存在实际错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 2018-09-15
  • 1970-01-01
  • 2011-09-22
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多