2

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);
3
  • What is this "different discussion"? Please provide a link. Commented Jul 8, 2016 at 9:25
  • I do not have a particular link. I read some post from matlab forum and random blog post. Commented Jul 8, 2016 at 10:53
  • The value of A is 512x1 double. Which is clearly insufficient to draw an image. Actual image size is 307x307x3 uint8. I have increased the buffersize and timeout-interval of UDP. Still not working. Commented Jul 8, 2016 at 15:26

1 Answer 1

5

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:

Sign up to request clarification or add additional context in comments.

Comments

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.