2010-12-14 32 views
6

He estado golpeando mi cabeza en esto por unos días.¿Es posible dibujar un rectángulo encima de AVCaptureVideoPreviewLayer?

Quiero dibujar un rectángulo encima de un CALayer (AVCaptureVideoPreviewLayer), que resulta ser la alimentación de video de la cámara en un iPhone4.

he aquí parte de mi configuración;

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

¿Esto es posible? Desde mi código actual, obtengo impresión de "capa hola", pero la alimentación de la cámara no tiene un rectángulo lleno.

Cualquier ayuda sería increíble. :)

Respuesta

1

Creo que debería agregar otra capa a AVCaptureVideoPreviewLayer y modifico el código de ejemplo para usted. Puedes probarlo.

//(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

o puede insertar sólo una imagen - se puede utilizar para la captura de vídeo AVCaptureVideoPreviewLayer obviamente, y crear otro CALayer() y utilizar layer.insertSublayer (..., arriba: ...) para insertar su " costumbre" capa por encima de la capa de vídeo, y por la costumbre me refiero todavía más que otro CALayer con let decir

layer.contents = spinner.cgImage 

Aquí hay un poco más detallada instructions for Swift

Cuestiones relacionadas