【问题标题】:Convert and display image from byte array从字节数组转换并显示图像
【发布时间】:2013-08-07 10:25:53
【问题描述】:

我正在制作一个程序,它从服务器获取有关字节数组中图像的数据。我正在将此数据转换为 24 位 BMP 格式(无论是 jpeg、png、bmp 还是 8-24-32bpp)。首先,我将其保存到我的 HD 中,然后将其加载到 JLabel 的图标中。完美运行,尽管在某些情况下我会遇到以下异常:

java.io.EOFException at
javax.imageio.stream.ImageInputStreamImpl.readFully(ImageInputStreamImpl.java:353) at
com.sun.imageio.plugins.bmp.BMPImageReader.read24Bit(BMPImageReader.java:1188) at
com.sun.imageio.plugins.bmp.BMPImageReader.read(BMPImageReader.java:843) at
javax.imageio.ImageIO.read(ImageIO.java:1448) at 
javax.imageio.ImageIO.read(ImageIO.java:1308)

对于这一行(第二行)

File imgFile = new File("d:/image.bmp");
BufferedImage image = ImageIO.read(imgFile);

在这些情况下:

  • 图像无法加载到 JLabel 中,但可以在我的 HD 上找到
  • 转换不正确,因为有些东西“滑倒”
  • 图片就像你在word文档中使用斜体时的样子

首先,我认为可能是 bpp 的问题,然后我认为可能是图片太大了,但我有案例可以工作,也有案例不能满足这两个建议。我有点卡在这里,很高兴有想法。

【问题讨论】:

  • 这些图片是您创建的吗?我能想到的只是它们是用 ImageIO 不支持的某种 BMP 格式创建的。也许如果您尝试编辑图像并再次保存它们。
  • 我认为问题在于某些图片没有 EOF 字节,这就是您收到 java.io.EOFException 的原因。我在使用jpeg 格式时遇到了同样的问题。如果您认为文件的元数据具有有关文件长度的信息,那么这很有意义,因此不需要 EOF。这个事实解释了为什么你的文件可以在你的 HD 中找到(我猜甚至可以打开)但你在 java 中得到了异常。
  • 查看this 链接,这里有我使用jpeg 图片的经验的解释,希望对您有所帮助。
  • @dic19 感谢您的想法!是的,它可以打开,但不能使用 imageIO。您的解决方案如何无法解决我的问题,但它很有用,因为现在我知道,我遇到异常的那些文件没有提到的 EOF 字节。另一件事,我将代码中的 system.arraycopy 行切换到了 arrays.copyof ,因为我收到了参数错误。
  • @Piro:是的,我已经创建了它们,服务器提供 RGB 值数据。我使用 Philipp C. Heckel 的位图编码器(版权)创建图像,并对其进行了一些修改

标签: java image swing javax.imageio


【解决方案1】:
  • 图片就像..当您在 Word 文档中使用斜体时

我想我现在终于明白这个项目符号的含义了.. ;-)

推测性的答案,但这里是:

如果您编写的图像看起来“歪斜”,则可能是由于 BMP 格式指定的每列缺少填充(或 BMP 标题中的宽度字段不正确)。然后,我假设您获得 EOF 异常的图像的宽度不是 4 的倍数。

尝试使用 ImageIO 编写 BMP,看看是否有帮助:

private static BufferedImage createRGBImage(byte[] bytes, int width, int height) {
    DataBufferByte buffer = new DataBufferByte(bytes, bytes.length);
    ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[]{8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
    return new BufferedImage(cm, Raster.createInterleavedRaster(buffer, width, height, width * 3, 3, new int[]{0, 1, 2}, null), false, null);
}

...

byte[] bytes = ...; // Your image bytes
OutputStream stream = ...; // Your output

BufferedImage image = createRGBImage(bytes, width, height);

try {
    ImageIO.write(image, "BMP", stream);
}
finally {
    stream.close();
}

【讨论】:

  • 你是天才,有问题的图像宽度为 618、2671、598 ......所有其他的宽度都是 4 的倍数。
  • @bajla 酷。我现在更新了答案,使用代码将 RGB 字节转换为BufferedImage。您可以使用它,除非您知道如何正确填充图像数据(据我所知,Philipp C. Heckel 的原始代码正确地完成了它,但我只是略过它)。
  • 先生,这是绝对的赢家解决方案!感谢更新。对此,我真的非常感激!这样图像显示速度更快,现在它适用于所有情况! :) :)
【解决方案2】:

通过类名调用它,liek ClassName.byteArrayToImage(byte):

public static BufferedImage  byteArrayToImage(byte[] bytes){  
        BufferedImage bufferedImage=null;
        try {
            InputStream inputStream = new ByteArrayInputStream(bytes);
            bufferedImage = ImageIO.read(inputStream);
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
        return bufferedImage;
}

【讨论】:

    【解决方案3】:

    您可以使用此代码将输出图像转换为字节数组

       Blob b = rs.getBlob(2);
       byte barr[] = new byte[(int)b.length()]; //create empty array
       barr = b.getBytes(1,(int)b.length());
    
       FileOutputStream fout = new FileOutputStream("D:\\sonoo.jpg");
       fout.write(barr);
    

    【讨论】:

    • 我不想将图像转换为 bytearray .. 第一行中的 'rs' 是什么?猜它是一张图片,但我一开始没有图片
    • rs 是 ResultSet 对象。
    猜你喜欢
    • 1970-01-01
    • 2014-07-21
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 2017-01-13
    相关资源
    最近更新 更多