2015-06-15 140 views
1

我理解Java上的套接字,并通过它发送Int,String,Byte等。从Java到Java通过套接字发送Mat对象

什么,我只是想知道是有办法解码垫对象字节数组,然后将其发送对Java插座,然后检索回从接收的字节垫目标?

Till Now this is What I have done

发送垫上插座

//Sending Mat over Socket 

Mat socketmat;  
long nbytes = socketmat.total() * socketmat.elemSize(); 
byte[] bytes = new byte[ (int) nbytes ]; 
socketmat.get(0, 0,bytes); 
mybytearray = bytes; 

dos = new DataOutputStream(os); 
dos.writeLong(nbytes); 
dos.write(mybytearray, 0, mybytearray.length); 

dos.flush(); 

用于接收垫上插槽

//Receiving Mat over Socket 

long len = clientData.readLong(); 
byte[] data = new byte[ (int) len]; 
if (len > 0) { 
    clientData.readFully(data); 
}    
byte[] bytes_ = data; 
result_mat.get(0, 0, bytes_); 
+0

@Newd ..是的,我现在提到它 –

+0

你试过ObjectOutputStream吗?这对你来说是一个很好的起点,因为它会自动处理序列化/反序列化。 – Danstahr

+0

Nah ...我没有任何关于序列化/反序列化的想法 –

回答

0

我觉得是用垫子使用JNI FileStorage类保存。

下面的代码可以用来垫保存为文件存储

FileStorage storage("image.xml", FileStorage::WRITE); 
storage << "img" << mat; 
storage.release(); 

然后采用Socket发送文件,然后从文件retrive垫回。

FileStorage fs("image.xml", FileStorage::READ); 
Mat img; 
fs >> img; 
-1

至于其他指出,您可以使用Serialization解决您的问题。你应该让你的Mat类实现Serializable接口。

下,而不是手动将对象转换为字节,你可以直接写你的对象,通过在ObjectOutputStream

ObjectOutputStream oos = new ObjectOutputStream(outputStream); 
oos.writeObject(mat); 

包裹你流在receival你可以以同样的方式提取对象。

ObjectInputStream ois = new ObjectInputStream(inputStream); 
Mat mat = (Mat)(ois.readObject()); 

而不是使用byte的沟通中,您可以通过更灵活的基于XML的通信替换上面。您可以让java为您使用JAXB(Java Architecture for Xml Binding)为您创建XML,这非常容易,而且与序列化非常相似。

// for sender 
JAXBContext jc = JAXBContext.newInstance(Mat.class); 
Marshaller marshaller = jc.createMarshaller(); 
marshaller.marshal(mat, outputStream); 

// for receiver 
JAXBContext jc = JAXBContext.newInstance(Mat.class); 
Unmarshaller unmarshaller = jc.createUnmarshaller(); 
Mat mat = unmarshaller.unmarshal(inputStream); 

在你的情况你的对象有本地引用。但是对于这个问题有一个简单的解决方案。只需通过创建一个包装类

import java.io.Serializable; 

public class MatWrapper implements Serializable { 
    int rows; 
    int cols; 
    int type; 
    byte[] data; 

    public MatWrapper() { 
    } 

    public MatWrapper(Mat mat) 
    { 
     if (mat.isContinuous()) { 

      int elemSize = (int) mat.elemSize(); 
      rows = mat.rows(); 
      cols = mat.cols(); 
      type = mat.type(); 

      data = new byte[cols * rows * elemSize]; 
      mat.get(0, 0, data); 
     } 
    } 

    public Mat toMat() 
    { 
     Mat mat = new Mat(rows, cols, type); 
     mat.put(0, 0, data); 
     return mat; 
    } 
} 

用法打破本土界限:

// convert Mat object to a wrapper object 
MatWrapper wrapper = new MatWrapper(mat); 

// this wrapper object is serializable 

// next on receiver-side 
MatWrapper wrapper = (MatWrapper)(ois.readObject); 
Mat mat = wrapper.toMat(); 
+0

评论不适用于扩展讨论;此对话已[移至聊天](http ://chat.stackoverflow.com/rooms/80697/discussion-on-answer-by-bvdb-sending-a-mat-object-over-socket-from-java-to-java)。 – meagar

+0

我收到以下mat.put(0,0,data)错误;'Caught Error:java.lang.UnsupportedOperationException:提供的数据元素编号(0)应该是Mat通道数的倍数(4) –

+0

抱歉,修正了愚蠢的错误(在构造函数中删除'byte []')。如果这能解决它,你能告诉我吗? – bvdb