2014-12-03 61 views
0

我想从台式机pc服务器(用C++编写的代码)将图像发送到android手机(显然是java)。我正在使用OpenCV加载和发送图像。在C++客户端上,我能够接收并显示图像,但是我无法在Android程序中执行此操作。使用javacv从套接字读取图像

如何从Android应用程序中使用javacv从套接字读取图像?

这里是工作的服务器代码(CV命名空间)的一部分:

if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR connecting"); 

Mat image = Mat::zeros(height, width, CV_8UC3); 
int imgSize = image.total()*image.elemSize(); 
uchar sockData[imgSize]; 

for (int i = 0; i < imgSize; i += n) { 
if ((n = recv(sockfd, sockData +i, imgSize - i, 0)) == -1) { 
    exit(1); 
    } 
} 
int ptr=0; 
for (int i = 0; i < image.rows; i++) { 
    for (int j = 0; j < image.cols; j++) { 
     image.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+ 0],sockData[ptr+1],sockData[ptr+2]); 
     ptr=ptr+3; 
    } 
} 

在Android应用我曾尝试:

newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
if (newsockfd < 0) 
     error("ERROR on accept"); 

Mat image; 
image = imread(FILE_PATH, CV_LOAD_IMAGE_COLOR); 
if(! image.data) { 
    return -1; 
} 
image = (image.reshape(0,1)); 
int imgSize = image.total()*image.elemSize(); 
// Sending data 
n = send(newsockfd, image.data, imgSize, 0); 
if (n < 0) 
     error("ERROR writing to socket"); 

工作的C++客户端代码(CV命名空间)的一部分用DataInputStream读取图像,但无法将其转换为位图并显示在屏幕上。 LogCat显示--- SkImageDecoder::Factory returned null,即使连接成功并且bytesRead值大于零且对于每个测试图像都不同。下面是我的实现:

private class MyClientThread implements Runnable { 

String dstAddress; 
int dstPort; 
private Socket socket; 

MyClientThread() { 
    dstAddress = "192.168.1.105"; 
    dstPort = 8072;   
} 

@Override 
public void run() { 
    try { 
     int bytesRead = 0; 
     InetAddress serverAddr = InetAddress.getByName(dstAddress); 
     socket = new Socket(serverAddr, dstPort); 
     try { 
      DataInputStream din = new DataInputStream(socket.getInputStream());    
      byte []imgData = new byte [1280*800]; 
      do{ 
       bytesRead = din.read(imgData, 0, imgData.length); 
       if (bytesRead > -1) //this causes to send and receive the same amount of bytes 
        totalBytesRead = totalBytesRead + bytesRead; 
      } while (bytesRead > -1); 

      bitmapimage = BitmapFactory.decodeByteArray(imgData, 0, totalBytesRead);     
     } catch (Exception e) { 
      Log.e("TCP", "S: Error", e); 
     } 
     finally {} 
     Log.i(TAG, String.valueOf(totalBytesRead)); 
     socket.close(); 
     imgView.setImageBitmap(bitmapimage); 
     imgView.invalidate();   
    } catch (UnknownHostException e1) { 
     e1.printStackTrace(); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    }  
} 

logcat的错误:

12-05 11:41:32.720: E/TCP(2496): S: Error 
12-05 11:41:32.720: E/TCP(2496): java.lang.ArrayIndexOutOfBoundsException 
12-05 11:41:32.720: E/TCP(2496): at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:515) 
12-05 11:41:32.720: E/TCP(2496): at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:545) 
12-05 11:41:32.720: E/TCP(2496): at com.example.javacvimagereceiver.MainActivity$MyClientThread.run(MainActivity.java:139) 
12-05 11:41:32.720: E/TCP(2496): at java.lang.Thread.run(Thread.java:818) 

其中线139:bitmapimage = BitmapFactory.decodeByteArray(imgData, 0, totalBytesRead);

+0

服务器发送了什么样的图像或图像文件? – greenapps 2014-12-03 16:58:25

+1

bytesRead是否总是等于发送的字节? – greenapps 2014-12-03 16:59:40

+0

这是一个.png文件。其实不然。它收到它发送的较少的字节。 – grzebyk 2014-12-03 17:05:35

回答

0

totalBytesRead > 1280*800因此ArrayIndexOutOfBoundsException。你必须连接ByteArrayOutputStream中的读取(google for bytearrayoutputstream示例,然后选择stackoverflow链接),而不是将它们覆盖到缓冲区中。 –   greenapps