0

クライアントから送信された JPEG 画像データが、不完全な画像のためにサーバーで読み取られたサイズと一致しない場合のクラッシュを防ぐ方法は?

  1. クライアント: 4 バイトの画像の長さ情報を送信-------->サーバー: 4 バイトを読み取ります。
  2. クライアント: x バイトの画像データを送信 --------------->サーバー: x バイトを読み取ります。

sampleBuffer(AVFoundation)を使ってiPhoneでJPEG画像を作成し、各画像の長さを送信してから画像データを送信しています。画像は時間間隔で連続して送信されます。Microsoft Vsual Studio 2005(C++) を使用してデータを受け取り、OpenCV を使用して画像を表示します。

iPhone (クライアント):

// AVCaptureSession delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer,0); 

    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer);  

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 

    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace);

    [self.customLayer performSelectorOnMainThread:@selector(setContents:) withObject: (id) newImage waitUntilDone:YES];

    UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight];
    NSData *data = UIImageJPEGRepresentation(image, 0.5);

    // Send image length bytes
    uint32_t length = (uint32_t)htonl([data length]);
    [_outputStream write:(uint8_t *)&length maxLength:4];

    // Send image data bytes
    [_outputStream write:(const uint8_t *)[data bytes] maxLength:[data length]];

    CGImageRelease(newImage);
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
    [pool drain];
}

PC - VS2005 C++ (サーバー):

cvNamedWindow("image", CV_WINDOW_AUTOSIZE);

std::vector<char> buf;

for(int i=0; i < 1000; i++) {

    typedef unsigned __int32 uint32_t;
    uint32_t len;
    int lengthbytes = 0;
    int databytes = 0; 

    // Receive image length bytes
    lengthbytes = recv(clientSocket, (char *)&len, sizeof(len), 0); 

    len = ntohl(len);

    buf.clear();
    buf.resize(len);

    // Receive image data bytes ()
    databytes = recv(clientSocket, &buf[0], buf.size(), 0);

    // Display image
    Mat matrixJpeg = imdecode(Mat(buf), 1);
    IplImage object = matrixJpeg;
    IplImage* fIplImageHeader = &object;
    cvShowImage("image", fIplImageHeader);
    cvWaitKey(50);
}
4

1 に答える 1

0

これが私の問題の解決策です:

cvNamedWindow("image", CV_WINDOW_AUTOSIZE);

std::vector<char> buf;

for(int i=0; i < 1000; i++) {

    typedef unsigned __int32 uint32_t;
    uint32_t len;
    int lengthbytes = 0;
    int databytes = 0; 

    // Receive image length bytes
    lengthbytes = recv(clientSocket, (char *)&len, sizeof(len), 0);

    len = ntohl(len);

    buf.clear();
    buf.resize(len);

    // Receive image data bytes      
    databytes = recv(clientSocket, &buf[0], buf.size(), 0);

    if ( buf[0] == (char)0xff && buf[1] == (char)0xd8 && buf[buf.size() - 2] == (char)0xff && buf[buf.size() -1] == (char)0xd9) {

        // Display image if it's a complete JPEG file with SOF = FF D8 and EOF = FF D9
        Mat matrixJpeg = imdecode(Mat(buf), 1);
        IplImage object = matrixJpeg;
        IplImage* fIplImageHeader = &object;
        cvShowImage("image", fIplImageHeader);
        cvWaitKey(50);

    }else{

        // Clear buffer and move to the SOF of the next image data
        buf.clear();
        buf.resize(2);

        while(recv(clientSocket, &buf[0], 1, 0) == 1){     
            if(buf[0] == (char)0xff) { 
                databytes1 = recv(clientSocket, &buf[1], 1, 0);
                if(buf[1] == (char)0xd9 ) { 
                    buf.clear();
                }
            }
        }
    }
} 
于 2013-03-25T06:33:20.387 に答える