2014-12-03 59 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