user1850484
user1850484

Reputation: 388

Sending an image between computers, from Java to MATLAB

I am trying to send an image file from one PC (the client) to another PC where MATLAB is running (the server) and the output image comes out empty.

From a different discussion, I understood that the main problem is some "Image Matrix mismatch" between Java and MATLAB. However, I do not fully understand the problem.

I would be grateful if you could give me some suggestions.

Client Java code:

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import javax.imageio.ImageIO;

public class myclientimage 
{
    public static void main(String args[]) throws IOException
    {
         BufferedImage img = ImageIO.read(new File("D:\\zzz.jpg"));
         ByteArrayOutputStream baos = new ByteArrayOutputStream();        
         ImageIO.write(img, "jpg", baos);
         baos.flush();
         byte[] buffer = baos.toByteArray();

         DatagramSocket clientSocket = new DatagramSocket();       
         InetAddress IPAddress = InetAddress.getByName("192.168.0.102");
         System.out.println(buffer.length);

         DatagramPacket packet = new DatagramPacket(buffer, buffer.length, IPAddress, 9091);

         clientSocket.send(packet);

         System.out.println("aaaa");
    }

}

Server MATLAB code:

udpA=udp('192.168.0.104', 9090,'LocalPort', 9091);
fopen(udpA);
A = fread(udpA, 200000);

du = reshape(A,size(A)); % converting vector du to 3d Image array 
imwrite(uint8(du), 'du.jpg'); %save our du to file du.jpg
I = imread('du.jpg'); %test if it saved correctly
imshow(I); 

fclose(udpA);

Upvotes: 2

Views: 747

Answers (1)

Mahdi Chamseddine
Mahdi Chamseddine

Reputation: 387

Ok so here's the solution. There is something that needs to be clarified first, we are sending the image as a compressed jpeg and not as independent pixels. Thus imwrite cannot be used for this purpose because it expects an image input (3D array). Then you should use fwrite instead.

Another (minor) issue is that reading a BufferedImage to bytes the way you are doing will give you a different size and I think you noticed this when you printed buffer.length and got a different size than what your computer reports. A solution to this can be found in the second answer of this question. However this has no effect on the image (maybe decreased quality?) the transmission worked for me with and without the solution mentioned in the link.

And as you already mentioned in your comment, that you are receiving 512 doubles. So basically there are 3 things that need to be done:

  1. Increasing the InputBufferSize of your UDP Object (default 512 bytes).
  2. Increasing the InputDatagramPacketSize of your UDP Object (default 8KB) unless you don't expect a file bigger than this size or you will be sending your file in chunks.
  3. converting the doubles to uint8 because this is how you are receiving them.

The final Java code:

public class SendImageUDP {
  public static void main(String args[]) throws IOException {
    BufferedImage img = ImageIO.read(new File("your_pic.jpg"));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(img, "jpg", baos);
    baos.flush();
    byte[] imageBuffer = baos.toByteArray();
    System.out.println(imageBuffer.length);

    InetAddress IPAddress = InetAddress.getByName("127.0.0.1"); // LocalHost for testing on the same computer
    DatagramSocket clientSocket = new DatagramSocket(9090, IPAddress); // Specify sending socket

    DatagramPacket packet = new DatagramPacket(imageBuffer, imageBuffer.length, IPAddress, 9091);
    clientSocket.send(packet);

    System.out.println("data sent");
    clientSocket.close();
  }
}

The final MATLAB code:

clear
close all

%% Define computer-specific variables

ipSender = '127.0.0.1'; % LocalHost for testing on the same computer
portSender = 9090;

ipReceiver = '127.0.0.1'; % LocalHost for testing on the same computer
portReceiver = 9091;

%% Create UDP Object

udpReceiver = udp(ipSender, portSender, 'LocalPort', portReceiver);
udpReceiver.InputBufferSize = 102400; % 100KB to be safe
udpReceiver.InputDatagramPacketSize = 65535; % Max possible

%% Connect to UDP Object

fopen(udpReceiver);
[A, count] = fread(udpReceiver, 102400, 'uint8'); % Receiving in proper format, big size just to be safe
A = uint8(A); % Just making sure it worked correctly

fileID = fopen('du.jpg','w'); % Save as a JPEG file because it was received this way
fwrite(fileID, A);
I = imread('du.jpg'); % Test if it saved correctly
imshow(I); 

%% Close

fclose(udpReceiver);
delete(udpReceiver);

As you can see from the MATLAB code, there is no need to reshape the received data because it's already compressed JPEG data, it's meaningless to reshape it anyway. Just write it to the file.

Sources:

Upvotes: 5

Related Questions