9

I'm making a program, which gets data about an image in byte array from a server. I'm converting this data into 24bit BMP format (whether its jpeg, png, bmp or 8-24-32bpp). First, I'm saving it to my HD, and then I'm loading it into a JLabel's Icon. Works perfectly, though there are some cases in which I get the following exception:

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)

For this line (the second)

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

In these cases:

  • the image does not load into the JLabel, but it can be found on my HD
  • the conversion is not proper, because something "slips"
  • the picture is like when you use italics in a word document

First, i thought maybe the bpp is the problem, then i thought that maybe the pictures are too large, but i have cases it works and cases it doesn't for both suggestions. I'm a little stuck here, and would be glad for ideas.

8
  • 1
    Did you created that images? All i can think of is that they are created with some format of BMP that ImageIO doesn't support. Maybe if you tried to edit images and save them again. Commented Aug 6, 2013 at 12:35
  • 1
    I think the issue is that some pictures doesn't have EOF bytes and that's why you're getting java.io.EOFException. I've experienced the same issue with jpeg format. It makes sense if you consider file's metadata have info about file's lenght and consequently EOF wouldn't be necessary. This fact explains why your files can be found in your HD (and even can be opened I guess) but you get exception in java. Commented Aug 6, 2013 at 12:41
  • 1
    Check this link, there's an explanation of my experience working with jpeg images that I hope be helpful. Commented Aug 6, 2013 at 12:45
  • @dic19 thanks for the idea! yes, it can be opened, but not with imageIO. Your solution howewer couldn't solve my problem, but it is useful, because now i know, that those files, which i got the exception on, does not have the mentioned EOF bytes. Another thing, I switched the system.arraycopy line in your code to arrays.copyof , because i got an error for the arguments. Commented Aug 7, 2013 at 9:36
  • @Piro: yes, i've created them, the server gives RGB values data. I create the images with Philipp C. Heckel's bitmapencoder (copyright) i modified it a little bit Commented Aug 7, 2013 at 9:39

3 Answers 3

7
  • the picture is like .. when You use italics in a word document

Think I finally got what this bullet item meant now.. ;-)

Speculative answer, but here goes:

If the image you write looks "skewed", it's probably due to missing padding for each column as the BMP format specifies (or incorrect width field in the BMP header). I assume then, that the images you get EOF exceptions for, is where the width is not a multiple of 4.

Try to write the BMPs using ImageIO to see if that helps:

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();
}
Sign up to request clarification or add additional context in comments.

3 Comments

you are genius, the problematic images have width 618, 2671, 598 ... all the others' width is a multiple of 4.
@bajla Cool. I updated the answer now, with code to convert RGB bytes to BufferedImage. You can use that, unless you figured out how to correctly pad your image data (from what I could understand, Philipp C. Heckel's original code did it correctly, but I only skimmed through it).
Sir, this is the absolute winner solution! thanks for the update. I really appreciate it! This way the image displaying is faster, and now it works in all cases! :) :)
2

Call it by class name, 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;
}

Comments

0

You can use this code to convert the output image to a byte Array

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

2 Comments

i don't want to convert image to bytearray .. and what is 'rs' in the first line? guess its an image, but i dont have an image in the first place
rs is the ResultSet object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.