2010-12-14 15 views
6

Pogrążyłem się w tej sprawie od kilku dni.Rysowanie prostokąta na wierzchu AVCaptureVideoPreviewLayer, możliwe?

Chcę narysować prostokąt na szczycie CALayer (AVCaptureVideoPreviewLayer), który jest po prostu źródłem wideo z kamery na iPhone4.

Oto część mojej konfiguracji;

//(in function for initialization) 

     -(void)initDevices { 
      AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput     deviceInputWithDevice:[AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo] error:nil]; 

      AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
      captureOutput.alwaysDiscardsLateVideoFrames = YES; 
      captureOutput.minFrameDuration = CMTimeMake(1, 30); 
      dispatch_queue_t queue; 
      queue = dispatch_queue_create("cameraQueue", NULL); 
      [captureOutput setSampleBufferDelegate:self queue:queue]; 
      dispatch_release(queue); 

      NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
      NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
      NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
      [captureOutput setVideoSettings:videoSettings]; 
      self.captureSession = [[AVCaptureSession alloc] init]; 
      [self.captureSession addInput:captureInput]; 
      [self.captureSession addOutput:captureOutput]; 
      [self.captureSession setSessionPreset:AVCaptureSessionPresetHigh]; 
      self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession]; 
      self.prevLayer.frame = CGRectMake(0, 0, 400, 400); 
      self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
      self.prevLayer.delegate = self; 
      [self.view.layer addSublayer: self.prevLayer]; 
    } 

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

     [self performSelectorOnMainThread:@selector(drawme) withObject:nil waitUntilDone:YES]; 
    } 

    - (void)drawme { 
[self.prevLayer setNeedsDisplay]; 
    } 

    //delegate function that draws to a CALayer 
    - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx { 
    NSLog(@"hello layer!"); 
    CGContextSetRGBFillColor (ctx, 1, 0, 0, 1); 
      CGContextFillRect (ctx, CGRectMake (0, 0, 200, 100)); 
    } 

Czy to możliwe? Z mojego obecnego kodu dostaję druk "cześć", ale kamera nie ma wypełnionego prostokąta.

Każda pomoc będzie świetna. :)

Odpowiedz

1

Myślę, że powinieneś dodać kolejną warstwę do AVCaptureVideoPreviewLayer i mogę zmodyfikować przykładowy kod dla ciebie. Możesz tego spróbować.

//(in function for initialization) 

    -(void)initDevices { 
     AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput     deviceInputWithDevice:[AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo] error:nil]; 

     AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
     captureOutput.alwaysDiscardsLateVideoFrames = YES; 
     captureOutput.minFrameDuration = CMTimeMake(1, 30); 
     dispatch_queue_t queue; 
     queue = dispatch_queue_create("cameraQueue", NULL); 
     [captureOutput setSampleBufferDelegate:self queue:queue]; 
     dispatch_release(queue); 

     NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
     NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
     NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
     [captureOutput setVideoSettings:videoSettings]; 
     self.captureSession = [[AVCaptureSession alloc] init]; 
     [self.captureSession addInput:captureInput]; 
     [self.captureSession addOutput:captureOutput]; 
     [self.captureSession setSessionPreset:AVCaptureSessionPresetHigh]; 
     self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession]; 
     self.prevLayer.frame = CGRectMake(0, 0, 400, 400); 
     self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
     [self.view.layer addSublayer:self.prevLayer]; 

     self.drawLayer = [CAShapeLayer layer]; 
     CGRect parentBox = [self.captureVideoPreviewLayer frame]; 
     [self.drawLayer setFrame:parentBox]; 
     [self.drawLayer setDelegate:self]; 
     [self.drawLayer setNeedsDisplay]; 
     [self.captureVideoPreviewLayer addSublayer:self.drawLayer]; 
} 

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

    [self performSelectorOnMainThread:@selector(drawme) withObject:nil waitUntilDone:YES]; 
} 

- (void)drawme { 
    [self.drawLayer setNeedsDisplay]; 
} 

//delegate function that draws to a CALayer 
- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx { 
    NSLog(@"hello layer!"); 
    CGContextSetRGBFillColor (ctx, 1, 0, 0, 1); 
    CGContextFillRect (ctx, CGRectMake (0, 0, 200, 100)); 
} 
0

Albo można wstawić tylko obraz - można użyć AVCaptureVideoPreviewLayer na przechwytywanie wideo oczywiście, i utworzyć inną CALayer() i używać layer.insertSublayer (... przede ...) aby wstawić " zwyczaj”warstwę powyżej warstwy wideo, a zwyczajowo to znaczy po prostu kolejna CALayer z powiedzmy

layer.contents = spinner.cgImage 

Oto nieco bardziej szczegółowy instructions for Swift

Powiązane problemy