2013-02-06 6 views
1

J'ai deux NSInputStream et NSOutputStream connectés l'un à l'autre via le réseau. Je souhaite transférer des objets de données de base et des images associées d'un périphérique vers un autre périphérique. J'ai converti avec succès les objets de données de base en JSON et transférés à l'autre côté du flux, puis rempli les données de base du JSON. Maintenant, il y a des images associées à chaque enregistrement. Les images sont sur le disque, seul le chemin est stocké dans les objets de données de base. Maintenant, vous devez avoir des données complètes à portée de main lorsque vous écrivez au output stream. J'ai le XML (qui contient JSON) prêt.
1. Mais comment transférer des images (NSData *) avec XML (également NSData *)? Comment vais-je différencier en fin de lecture (NSInputStream) entre XML et Images?
2. De plus, je dois transférer plusieurs images, comment pouvons-nous dire à la fin NSInputStream que les octets d'une image ont fini et que les octets de l'image suivante ont commencé?
3. Comment savons-nous quelle image (nom) a été transférée?
MerciTransfert de plusieurs images via NSInputStream/NSOutputStream

Répondre

0

Je l'ai résolu en suivant les étapes suivantes:
1. Convertir chaque objet géré à NSDictionary
2. Mettez tous les dictionnaires dans NSArray
3. Convertir le NSArray-NSData en utilisant NSKeyedArchiver
4. Transférer NSData à travers les flux

Et à la fin du récepteur, je suis inversé au-dessus s teps.
Merci Marius Kurgonas

0

Convertir NSData (de chaque UIImage) à la représentation NSString, puis mettre tous les objets dans NSStringNSDictionary et sérialisent ce dictionnaire. De cette façon, lorsque vous transférez des données, vous pouvez inverser le processus pour extraire des images en sachant quels points clés à quelle image. De cette façon, vous devriez être en mesure de transférer plusieurs images.

Espérons que cela aide.

Vive

+0

Merci cher. Votre réponse m'a conduit à la solution. –

0

Semble ridicule, chaque réponse. Essayez quelque chose comme ceci:

case NSStreamEventHasBytesAvailable: { 
            NSLog(@"NSStreamEventHasBytesAvailable"); 
            uint8_t * mbuf[DATA_LENGTH]; 
            mlen = [(NSInputStream *)stream read:(uint8_t *)mbuf maxLength:DATA_LENGTH]; 
            NSLog(@"mlen == %lu", mlen); 
            [mdata appendBytes:(const void *)mbuf length:mlen]; 
            NSLog(@"mdata length == %lu", mdata.length); 
            if (mlen < DATA_LENGTH) { 
                NSLog(@"displayImage"); 
                UIImage *image = [UIImage imageWithData:mdata]; 
                [self.peerConnectionViewController.view.subviews[0].layer setContents:(__bridge id)image.CGImage]; 
                mdata = nil; 
                mlen  = DATA_LENGTH; 
                mdata = [[NSMutableData alloc] init]; 
            } 
        } break; 
  

...

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 
    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); 
    UIImage *image = [[UIImage alloc] initWithCGImage:newImage scale:1 orientation:UIImageOrientationUp]; 
    CGImageRelease(newImage); 
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 
     
    NSData *data = [NSData dataWithData:UIImageJPEGRepresentation(image, 0.25)]; 
     
    __block BOOL baseCaseCondition = NO; // obviously this should be data driven, not hardcoded 
    __block NSInteger _len = DATA_LENGTH; 
    __block NSInteger _byteIndex = 0; 
    typedef void (^RecursiveBlock)(void (^)()); 
    RecursiveBlock aRecursiveBlock; 
     
    aRecursiveBlock = ^(RecursiveBlock block) { 
        NSLog(@"Block called..."); 
        baseCaseCondition = (data.length > 0 && _byteIndex < data.length) ? TRUE : FALSE; 
        if ((baseCaseCondition) && block) 
        { 
            _len = (data.length - _byteIndex) == 0 ? 1 : (data.length - _byteIndex) < DATA_LENGTH ? (data.length - _byteIndex) : DATA_LENGTH; 
            // 
            NSLog(@"START | byteIndex: %lu/%lu  writing len: %lu", _byteIndex, data.length, _len); 
            // 
            uint8_t * bytes[_len]; 
            [data getBytes:&bytes range:NSMakeRange(_byteIndex, _len)]; 
            _byteIndex += [self.outputStream write:(const uint8_t *)bytes maxLength:_len]; 
            // 
            NSLog(@"END | byteIndex: %lu/%lu wrote len: %lu", _byteIndex, data.length, _len); 
            // 
            dispatch_barrier_async(dispatch_get_main_queue(), ^{ 
                block(block); 
            }); 
        } 
    }; 
     
    if (self.outputStream.hasSpaceAvailable) 
            aRecursiveBlock(aRecursiveBlock); 
} 
  

Questions connexes