在计算机之间发送图像,从 Java 到 MATLAB
Sending an image between computers, from Java to MATLAB
我正在尝试将图像文件从一台 PC(客户端)发送到另一台 MATLAB 运行(服务器)PC,但输出图像为空。
从不同的讨论中,我了解到主要问题是 Java 和 MATLAB 之间的一些 "Image Matrix mismatch"。但是,我没有完全理解这个问题。
如果您能给我一些建议,我将不胜感激。
客户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);
好的,这就是解决方案。首先需要澄清的是,我们将图像作为压缩的 jpeg 而不是独立像素发送。因此 imwrite
不能用于此目的,因为它需要图像输入(3D 数组)。那么你应该使用 fwrite
来代替。
另一个(小)问题是,按照您的方式将 BufferedImage
读取为字节会给您不同的大小,我想您在打印 buffer.length
时注意到了这一点并得到了不同的比您的计算机报告的大小。可以找到解决此问题的方法 in the second answer of this question。然而,这对图像没有影响(可能会降低质量?)无论有没有 link.
中提到的解决方案,传输都对我有用
正如您在评论中提到的,您收到了 512 个双打。所以基本上有 3 件事需要做:
- 增加您的 UDP 对象的
InputBufferSize
(默认 512 字节)。
- 增加 UDP 对象的
InputDatagramPacketSize
(默认 8KB),除非您不希望文件大于此大小,否则您将分块发送文件。
- 将双精度数转换为 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代码可以看出,接收到的数据不需要reshape,因为已经是压缩过的JPEG数据,反正reshape也没意义。直接写入文件即可。
来源:
- UDP Object
- FREAD function for UDP
- InputBufferSize
- Very helpful implementation of UDP in MATLAB
- The question mentioned above for getting true file size
我正在尝试将图像文件从一台 PC(客户端)发送到另一台 MATLAB 运行(服务器)PC,但输出图像为空。
从不同的讨论中,我了解到主要问题是 Java 和 MATLAB 之间的一些 "Image Matrix mismatch"。但是,我没有完全理解这个问题。
如果您能给我一些建议,我将不胜感激。
客户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);
好的,这就是解决方案。首先需要澄清的是,我们将图像作为压缩的 jpeg 而不是独立像素发送。因此 imwrite
不能用于此目的,因为它需要图像输入(3D 数组)。那么你应该使用 fwrite
来代替。
另一个(小)问题是,按照您的方式将 BufferedImage
读取为字节会给您不同的大小,我想您在打印 buffer.length
时注意到了这一点并得到了不同的比您的计算机报告的大小。可以找到解决此问题的方法 in the second answer of this question。然而,这对图像没有影响(可能会降低质量?)无论有没有 link.
正如您在评论中提到的,您收到了 512 个双打。所以基本上有 3 件事需要做:
- 增加您的 UDP 对象的
InputBufferSize
(默认 512 字节)。 - 增加 UDP 对象的
InputDatagramPacketSize
(默认 8KB),除非您不希望文件大于此大小,否则您将分块发送文件。 - 将双精度数转换为 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代码可以看出,接收到的数据不需要reshape,因为已经是压缩过的JPEG数据,反正reshape也没意义。直接写入文件即可。
来源:
- UDP Object
- FREAD function for UDP
- InputBufferSize
- Very helpful implementation of UDP in MATLAB
- The question mentioned above for getting true file size