Search code examples
javasocketsjavax.imageiobytebufferbytearrayoutputstream

ImageIO write only load half the picture (socket)


I'm trying to send an image from client to server using socket. I am able to send the image to server directory, but the image sent is not full. What should I change?

Client code :

Part filePart = request.getPart("file"); 
InputStream fileContent = filePart.getInputStream();        

Socket clientSocket = new Socket("localhost",51519);
OutputStream outputStream = clientSocket.getOutputStream();
try {                       
    BufferedImage image = ImageIO.read(fileContent);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ImageIO.write(image, "jpg", byteArrayOutputStream);

    byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();

    outputStream.write(size);
    outputStream.write(byteArrayOutputStream.toByteArray());                   
}
catch (SocketException ex){
    BLL_Common.write_log(ex.toString(), "");
} catch (IOException ex) {
    BLL_Common.write_log(ex.toString(), "");
} finally {
    outputStream.flush();     
}

Server code :

String dir = "web/Admin/img/";     
ServerSocket serverSocket = new ServerSocket(51519);

while(true) {
 try {
  Socket socket = serverSocket.accept();

  InputStream inputStream = socket.getInputStream();

  byte[] sizeAr = new byte[4];
  inputStream.read(sizeAr);
  int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
  byte[] imageAr = new byte[size];

  inputStream.read(imageAr);
  BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));                 

  String fileName = String.valueOf(System.currentTimeMillis());

  ImageIO.write(image, "jpg", new File(dir + fileName + ".png"));
 } 
 catch (SocketException ex) {
  //...
 } catch (IOException ex) {
  //...
 } 
} 

This is the image loaded : enter image description here


Solution

  • You're assuming that read() fills the buffer. You need DataInputStream.readFully().

    Have a look at DataOutputStream.writeInt() while you're at it.

    Of course you could just use ImageIO.read() directly on the socket input stream and avoid all this, and similarly ImageIO.write() directly to the socket output stream. But unless the original image isn't a JPEG you should just be copying bytes, without using ImageIO or BufferedImage at all.