0

As stated, I am trying to send an Image from a Java Server to an Android Client. It worked using Base64, which only worked with png's for me, but that was too slow for my liking, so i wanted to try it with a jpg.

I used Bytearrays and I know that you have to first send the size, then the actual image, which i did.

What happens now is that the first time i send the image, the correct size is sent and the image is displayed (relatively) correctly. But when the image is too large, (keep in mind, the size that is communicated is still correct), some of the image is cut off. It's just not transmitted yet, but the android client just goes with what it has. The problem is, that the missing bytes are somehow still in the InputStream, so next time i try to download the image, the size is waaaaaayyyyy off, sometimes in the negatives. I am assuming that the missing bytes from the last image are just added in front of the size-Bytes of the second image, which crashes the programm.

I tried sleeping the thread at and for different times, which has an impact, but doesn't fix the problem completely. It would help if anybody knew, how i could safely get rid of the lasting bytes, or even better, make it so that the full image is displayed and the client doesn't just go on with half of the bytes.

This is the method in question of the client:

{
out.println("screenshot");
Log.d("screenshot", "try getting screenshot");

InputStream is = s.getInputStream();

byte[] sizeAr = new byte[8];

is.read(sizeAr);

int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
                                
Log.d("screenshot", "size: " + size);

//thread.sleep(600);

byte[] imageAr = new byte[size];

//thread.sleep(600);

is.read(imageAr);

//thread.sleep(600);

final Bitmap decodedBitmap = BitmapFactory.decodeByteArray(imageAr, 0, size);

//...and display of image
}

And here's the server code sniplet


image = ImageIO.read(new File("./res/testimage.jpg"));

OutputStream outputStream = socket.getOutputStream();
                        
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayOutputStream);
                        
byte[] result = byteArrayOutputStream.toByteArray();
                    
//os.writeBytes("size coming."+ "\n");
//os.flush();
                        
byte[] size = ByteBuffer.allocate(8).putInt(result.length).array();
outputStream.write(size);
                        
System.out.println("size: " + result.length);
                    
//thread.sleep(500);
                    
outputStream.write(result);
                    
thread.sleep(500);
                    
//outputStream.flush();

this is roughly how an image would look. (after this, the next time i press screenshot, the app crashes) Many thanks in advance :)

enter image description here

Maihoo
  • 31
  • 6
  • 2
    `int nread = is.read(imageAr);` Check the return value of read() as it might read less bytes then you think it would. – blackapps Nov 02 '20 at 19:11
  • @blackapps (transmitted size value | nread): first(105457 | 105457), second(105457 | 21760). What does that mean? Is nread the number of bytes actually transmitted? If so, what can i do to fix this? Thanks in advance – Maihoo Nov 02 '20 at 19:26
  • 1
    `nread` is the `n`umber of bytes actually `read`. Make a loop with repeated read() until you read exactly the amount of bytes indicated by your `size` parameter. – blackapps Nov 02 '20 at 21:06
  • 1
    How it works: `nread = is.read(imageAr, 12, 100);` You ask to read 100 bytes to be put in your buffer starting from 12th byte. nread will be equal or less than 100. – blackapps Nov 02 '20 at 21:10
  • 1
    You don't need `ImageIO` for this. Just send the bytes, and be careful not to overrun the expected length. See my answer in the duplicate. – user207421 Nov 02 '20 at 23:14
  • That should surely be enough. I had it working so that all bytes were read, but the resulting image was very glitchy. Some larger areas that are okay, but with the wrong colors and so on, but that should be fixable. Thank you all @blackapps and MarquisofLorne . Edit: I wouldn't call myself a "competent programmer" yet by the way. Much rather a bloody beginner – Maihoo Nov 03 '20 at 00:03
  • 1
    @blackapps Nothing 'rude' about my actions here. The remarks you quote were addressed to someone else in the duplicate, and were completely justified, as any fair reading of the exchange will show. I am unable to understand you. – user207421 Nov 03 '20 at 00:06
  • Alright, i got it working. No reason to argue, thanks 4 the help, guys. I am relatively new to all of this, so please excuse my inability to navigate this site. – Maihoo Nov 03 '20 at 00:19

0 Answers0