【问题标题】:How to read Bytes of an Image in Java?如何在 Java 中读取图像的字节数?
【发布时间】:2014-02-13 14:50:17
【问题描述】:

我目前正在使用 Java 进行图像处理。最初我使用 ImageIO 类来编写图像

ImageIO.write(image,"jpg",os);

这种方法的问题是丢失了实际的图像大小和质量。然后我更喜欢ByteStream

Files.readAllBytes(fi.toPath());

阅读和

fos.write(fileContent);

写图像。这完美地工作。我在这里面临的问题是我只能读取文件但不能读取图像(即 BufferedImage 图像)。是否可以在这里读取图像而不是文件,或者我应该转移到其他 IO 吗?

代码片段在这里,

try {

File fnew=new File("d:\\3\\IMG1.jpg"); 
java.io.FileOutputStream fos = new java.io.FileOutputStream(new             File("d:\\3\\Test1\\4.jpg"));
File fi = new File("d:\\3\\7.jpg");
byte[] fileContent = Files.readAllBytes(fi.toPath());
fos.write(fileContent);

} catch (Exception e) {

System.out.println("Exception");
}

我们将不胜感激任何类型的建议或帮助。提前致谢。

【问题讨论】:

  • 我的输入类型只是图像而不是文件。 :-(
  • 您可以编辑问题并添加额外的详细信息
  • @Laxman - 我正在处理图像(读取图像、更改质量、调整大小、设置水印并最终将其写入目的地)。问题是如果我使用 ImageIO.write() 那么我在写作时会失去实际的图像质量。所以我转移到 FileOutputStream 并读取 byte[]。我的问题是当输入是图像时是否有可能读取图像的字节,或者我应该使用其他 IO 吗?
  • @J_User 阅读图像不是问题。使用不同的 IO 将无济于事。是 Bitmap 和 JPEG 之间的转换影响了质量。
  • @Navin 我只获取 JPEG 图像作为我的输入。我不会在我的流程中的任何地方更改其格式。 ImageIO.write() 会改变图片格式吗?

标签: java image inputstream javax.imageio fileoutputstream


【解决方案1】:

这种方法的问题是丢失了实际的图像大小和质量。然后我更喜欢ByteStream

当您使用 ImageIO 读取 JPEG 时,它会自动将 JPEG 转换为位图。然后,当您编写它时,它再次编码为 JPEG(这会降低质量)。

只需将ImageIO.write(image,"jpg",os) 替换为ImageIO.write(image,"png",os) 即可。 PNG等无损格式在写入图像时不会丢失任何数据。

【讨论】:

  • 我的输出文件应该是 JPEG。这就是问题所在。 ImageIO.write() 中不可能无损 jpg 文件写入,我猜..!
  • @J_User 如果不支持无损 JPEG,则必须使用其他库。为什么需要JPEG?它实际上是最差的图像格式。
【解决方案2】:

BufferedImage getRGB() 将为您获取图像的所有实际像素数据。不会有压缩或类似JPEG的任何东西。它将是原始图像。

根据我的 cmets 编辑添加示例...

    BufferedImage image = ImageIO.read(new File("google.jpg"));
    ImageWriter w = ImageIO.getImageWritersBySuffix("jpg").next();
    ImageOutputStream out = ImageIO.createImageOutputStream(new File("output.jpg"));
    w.setOutput(out);
    ImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault());
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(1);
    w.write(null, new IIOImage(image, null, null), param);
    out.close();

【讨论】:

  • JPEG 文件不存储 RGB 像素。 DCT 会有一些错误。他在写图像时必须使用无损格式。
  • 如果质量是唯一的关注点(不是原始数据),您将使用 ImageIO 获取 ImageWriter,然后使用 ImageWriterParam 设置质量。
  • 正如我在另一条评论中对(现在已删除?)答案所写的那样,没有办法在不损失质量的情况下编写 JPEG。如果原始文件是 JPEG,理论上您可以通过使用完全相同的霍夫曼表获得近乎无损的重新压缩。
  • 有无损 JPEG,只是它不是标准 JDK 的一部分。第三方库支持它。也就是说,上面质量设置为 100% 的代码非常接近。
  • 不,您只会生成大文件。质量仍然会比原版差,除非原版是用相同的表格压缩的(不太可能)。 JPEG-Lossless 或 JPEG-LS 可以工作,但这有点人为,因为它们是完全不同的算法,工具支持较少,并且可能首先破坏了使用 JPEG 的目的。只需使用 PNG 或 TIFF。 :-)
猜你喜欢
  • 2010-12-01
  • 2015-04-07
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
相关资源
最近更新 更多