代码之家  ›  专栏  ›  技术社区  ›  user1850484

在计算机之间发送图像,从Java到MATLAB

  •  2
  • user1850484  · 技术社区  · 8 年前

    我正在尝试将图像文件从一台PC(客户端)发送到另一台运行MATLAB的PC(服务器),输出图像为空。

    从不同的讨论中,我了解到主要问题是Java和MATLAB之间的“图像矩阵不匹配”。然而,我并不完全理解这个问题。

    如果你能给我一些建议,我将不胜感激。

    客户端Java代码:

    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");
        }
    
    }
    

    服务器MATLAB代码:

    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);
    
    1 回复  |  直到 8 年前
        1
  •  5
  •   Community Patrick Maupin    7 年前

    好的,这是解决方案。有一点需要首先澄清,我们将图像作为压缩jpeg而不是独立像素发送。因此 imwrite 无法用于此目的,因为它需要图像输入(3D数组)。那么你应该使用 fwrite 相反

    另一个(次要)问题是读取 BufferedImage 以字节为单位,这样做会给你一个不同的大小,我想你在打印时注意到了这一点 buffer.length 和电脑报告的尺寸不同。可以找到解决方案 in the second answer of this question 然而,这对图像没有影响(可能会降低质量?)无论有没有链接中提到的解决方案,传输都对我有效。

    正如您在评论中提到的,您将收到512份双份。因此,基本上需要做三件事:

    1. 增加 InputBufferSize UDP对象(默认512字节)。
    2. 增加 InputDatagramPacketSize UDP对象的大小(默认为8KB),除非您不希望文件大于此大小,否则您将以块的形式发送文件。
    3. 将double转换为uint8,因为这是您接收它们的方式。

    最后的Java代码:

    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();
      }
    }
    

    最终MATLAB代码:

    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);
    

    正如您从MATLAB代码中看到的那样,没有必要对接收到的数据进行整形,因为它已经是压缩的JPEG数据,无论如何,对其进行整形都是毫无意义的。只需将其写入文件即可。