0

This code loads an image in a BufferedImage object. ImageIO.read() may take an InputStream as an argument.

I first tried getting an InputStream from a socket and loading. Then I tried loading the image in an array of bytes and giving this array as argument (I thought that the problem was in the connection).

Both ways work fine when I run my program through Eclipse and both of them don't work when I save my project as a runnable jar file. The code stuck at the last line.

byte[] buffer = new byte[imageBufferSize];
int count = 0;
while ((count = in.read(buffer)) != -1) {
    //nothing here. Just reading in buffer in while cycle.
}
String bytesStr = new String(buffer);
int skipPos = bytesStr.indexOf("‰PNG");
byte[] newBytes = Arrays.copyOfRange(buffer, skipPos, buffer.length);
bufImg = ImageIO.read(new ByteArrayInputStream(newBytes));
Stephen P
  • 14,422
  • 2
  • 43
  • 67
  • 1
    have you tried putting this in a try catch clause - if so, what is the exception? – ali haider Aug 04 '14 at 20:25
  • 1
    also, how are you creating the jar file – ali haider Aug 04 '14 at 20:26
  • I tried. Didn't catch any exceptions. But it doesn't stuck as I said before. It goes to finally block of try-catch. About creating - I just export it as Runnable jar file in Eclipse and it always builds normally. Also I checked .jar file. All libraries I used are there. – Serhii Tereshchenko Aug 04 '14 at 20:34
  • is bufImg null in the finally clause? – ali haider Aug 04 '14 at 20:35
  • Your buffer-reading while loop is bogus. It will only work (by accident) if you happen to read `imageBufferSize` bytes in one go. Use the `read(byte[], int, int)` method, set the start offset to 0, and add count for each iteration of the while loop. – Harald K Aug 04 '14 at 20:56
  • I know this. My image size is always less than imageBufferSize. "While" loop isn't needed here. But anyway thanks for advice :) My miss. But anyway my app stalls because of other reason. And I still can't understand why. – Serhii Tereshchenko Aug 04 '14 at 21:03
  • While loop *is* needed (unless you can guarantee that `in.read(buffer)` will read all data in one go, but then you must be using a special-purpose `InputStream` implementation that I don't know of...). – Harald K Aug 04 '14 at 21:08
  • [This](http://stackoverflow.com/questions/18505406/java-tcp-can-only-retrieve-image-once/18509880#18509880) might only be partially relevant, but demonstrates an idea for writing an image, via a socket, using ImageIO and reading it again, via another socket, via ImageIO – MadProgrammer Aug 04 '14 at 21:41

1 Answers1

0

As mentioned in my comment, the problem is likely that your while-loop doesn't do what you expected (the problem is that for each iteration, it will overwrite buffer from the beginning, producing garbled data in buffer). To properly read all of the input stream into buffer, use the following code:

byte[] buffer = new byte[imageBufferSize];
int count = 0;
int offset = 0;

while ((count = in.read(buffer, offset, imageBufferSize - offset)) != -1) {
    offset += count;
}

The reason why bufImg is null is probably just because ImageIO.read(..) returns null for data it doesn't understand.

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • I edited my code as you said, but it still doesn't work. The first time I just used to create input stream with java.net.URLConnection.getInputStream() for my image. But it gave the same result. So unfortunately error isn't in this code. – Serhii Tereshchenko Aug 04 '14 at 21:16
  • Also the main problem that I can't understand is that all this code works fine when running in Eclipse. – Serhii Tereshchenko Aug 04 '14 at 21:22
  • Try dumping `buffer` or `newBytes` to disk, and look at them in a hex editor. Both with and without Eclipse. Can you look at the network traffic? Maybe Eclipse adds some "magic" headers to the `HttpURLConnection`? I've seen weirder things... Have you tried using a `FileInputStream` with a known good file, just to take away some of the variables? – Harald K Aug 04 '14 at 21:24
  • I used to do it before. It's alright. The image is correct. The one thing, that may be helpful is that my program may download picture with proxy and directly. And only direct download doesn't work. When I create the same socket but through proxy and get its' stream (or create java.net.URLConnection through proxy), it works fine without Eclipse. – Serhii Tereshchenko Aug 04 '14 at 21:31
  • Some updates. I used to catch Exception in my try-catch clause. And now I tried to catch and print Throwable. And as I expected - it is Error: java.lang.NoClassDefFoundError: Could not initialize class javax.imageio.ImageIO. So in Eclipse it initializes normally, without Eclipse it crashes. Any ideas? :) – Serhii Tereshchenko Aug 04 '14 at 21:40
  • Edit question and update with new full code and full stack trace. Also, what JRE are you using? Normally, ImageIO is a core class, so it should be found... – Harald K Aug 04 '14 at 21:48
  • I use 1.7. I think that now I may try to find answer by myself in existing same questions. If I won't, I will get back there or create a new one. Thank you very much for help. – Serhii Tereshchenko Aug 04 '14 at 21:56