【问题标题】:Transfer Multiple Images via NSInputStream/NSOutputStream通过 NSInputStream/NSOutputStream 传输多个图像
【发布时间】:2013-02-06 11:44:27
【问题描述】:

我有两个NSInputStreamNSOutputStream 通过网络相互连接。我想将核心数据对象和相关图像从一台设备传输到另一台设备。我已成功将核心数据对象转换为JSON 并传输到流的另一端,然后从JSON 填充核心数据。现在有与每个记录相关联的图像。图像在光盘上,只有路径存储在核心数据对象中。现在,当您写信给output stream 时,您必须手头有完整的数据。我准备好了XML(包含JSON)。
1. 但是我如何传输图像(NSData *)和XML(也是NSData *)?如何在阅读端 (NSInputStream) 区分 XML 和图像?
2. 另外,我要传输多个图像,我们如何在NSInputStream 端判断一个图像的字节已经完成并且下一个图像的字节已经开始?
3.我们怎么知道哪个图像(名称)被转移了?
谢谢

【问题讨论】:

    标签: ios image nsstream nsinputstream nsoutputstream


    【解决方案1】:

    NSData(每个UIImage)转换为NSString表示,然后将所有NSString对象放入NSDictionary并序列化该字典。这样,当您传输数据时,您可以反转过程以提取图像,知道哪些关键点指向哪个图像。这样你就可以传输多张图片了。

    希望这会有所帮助。

    干杯

    【讨论】:

    • 谢谢亲爱的。您的回答使我找到了解决方案。
    【解决方案2】:

    我通过以下步骤解决了这个问题:
    1.将每个托管对象转换为NSDictionary
    2. 将所有字典放入NSArray
    3. 使用NSKeyedArchiverNSArray 转换为NSData
    4. 通过流传输NSData

    在接收端,我颠倒了上述步骤。
    谢谢马吕斯·库尔戈纳斯

    【讨论】:

      【解决方案3】:

      听起来很荒谬,每个答案。试试这样的:

      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);
      }
       
      

       

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-04
        • 2011-10-24
        • 1970-01-01
        相关资源
        最近更新 更多