Java 从字节数组转换和显示图像

Java 从字节数组转换和显示图像,java,image,swing,javax.imageio,Java,Image,Swing,Javax.imageio,我正在制作一个程序,它从服务器获取字节数组中的图像数据。我正在将这些数据转换为24位BMP格式(无论是jpeg、png、BMP还是8-24-32bpp)。首先,我将其保存到我的HD,然后将其加载到JLabel的图标中。虽然在某些情况下我会遇到以下例外情况,但效果非常好: java.io.EOFException at javax.imageio.stream.ImageInputStreamImpl.readFully(ImageInputStreamImpl.java:353) at com.

我正在制作一个程序,它从服务器获取字节数组中的图像数据。我正在将这些数据转换为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)
这一行(第二行)

在这些情况下:

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

首先,我认为bpp可能是问题所在,然后我认为可能图片太大了,但我有两种情况,一种是有效的,另一种是无效的。我有点被困在这里了,我很乐意提出一些想法。

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

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

按类名liek
ClassName.byteArrayToImage(字节)
调用它:

  • 这幅画像。。在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);
}


我不想将图像转换为bytearray。。第一行的“rs”是什么?我猜这是一个图像,但我没有一个图像放在首位,因为它是ResultSet对象。你创建了那个图像吗?我所能想到的是,它们是用ImageIO不支持的BMP格式创建的。如果您尝试编辑图像并再次保存它们,可能会出现问题。我认为问题在于某些图片没有EOF字节,这就是为什么会出现
java.io.EOFException
。我在使用
jpeg
格式时也遇到过同样的问题。如果你认为文件的元数据有文件长度的信息,那么EOF就没有必要了。这一事实解释了为什么您的文件可以在HD中找到(我想甚至可以打开),但在java中会出现异常。检查链接,这里有一个关于我使用
jpeg
图像的经验的解释,希望对您有所帮助。@dic19谢谢您的想法!是的,它可以打开,但不能用imageIO打开。您的解决方案howewer无法解决我的问题,但它很有用,因为现在我知道,我得到异常的那些文件没有提到的EOF字节。另一件事,我将代码中的system.arraycopy行切换到arrays.copyof,因为我的参数有一个错误。@Piro:是的,我创建了它们,服务器提供了RGB值数据。我用Philipp C.Heckel的bitmapencoder创建图像(版权所有)我对它做了一点修改你是天才,有问题的图像宽度为618,2671,598。。。所有其他宽度都是4的倍数。@bajla Cool。我现在更新了答案,使用代码将RGB字节转换为
buffereImage
。您可以使用它,除非您知道如何正确地填充图像数据(据我所知,Philipp C.Heckel的原始代码做得很正确,但我只是浏览了一下)。先生,这是绝对的赢家解决方案!谢谢你的更新。我真的很感激!这样,图像显示速度更快,现在它在所有情况下都能正常工作!:):)
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;
}
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();
}