【问题标题】:Drawing a rectangle on top of a AVCaptureVideoPreviewLayer, possible?在 AVCaptureVideoPreviewLayer 上绘制一个矩形,可能吗?
【发布时间】:2010-12-14 02:36:31
【问题描述】:

这几天我一直在纠结这个问题。

我想在 CALayer (AVCaptureVideoPreviewLayer) 上绘制一个矩形,这恰好是 iPhone4 上摄像头的视频源。

这是我设置的一部分;

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

这甚至可能吗?从我当前的代码中,我得到了“hello layer”打印,但是相机馈送没有填充的矩形。

任何帮助都会很棒。 :)

【问题讨论】:

    标签: ios drawing camera iphone-4


    【解决方案1】:

    我认为您应该向 AVCaptureVideoPreviewLayer 添加另一个图层,我会为您修改示例代码。你可以试试。

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

    【讨论】:

      【解决方案2】:

      或者你可以只插入一个图像 - 你可以使用 AVCaptureVideoPreviewLayer 来捕捉视频,然后创建另一个 CALayer() 并使用 layer.insertSublayer(..., above: ...) 在上面插入你的“自定义”层视频层,通过自定义,我的意思是另一个 CALayer,让我们说

      layer.contents = spinner.cgImage
      

      这里有更详细的instructions for Swift

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多