ios通过AVCaptureSession获取视频流、照片

        在使用到AVCaptureSession获取视频流、照片时,由于硬件采集到的数据跟设备方向有关,导致直接从缓冲区读取到图片或视频,可能存在无法正常显示的问题。此时需要做相应的转换。

        具体关于概念上的解释,可参考http://www.cocoachina.com/ios/20150605/12021.html这篇博文。

调用硬件设备

- (AVCaptureVideoDataOutput *)captureOutput {
    if (!_captureOutput) {
        _captureOutput = [[AVCaptureVideoDataOutput alloc]
                                                   init];
        _captureOutput.alwaysDiscardsLateVideoFrames = YES;
        dispatch_queue_t queue;
        queue = dispatch_queue_create("cameraQueue", NULL);
        [_captureOutput setSampleBufferDelegate:self queue:queue];
        NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
        NSNumber* value = [NSNumber
                           numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
        NSDictionary* videoSettings = [NSDictionary
                                       dictionaryWithObject:value forKey:key];
        [_captureOutput setVideoSettings:videoSettings];
    }

    return _captureOutput;
}

- (AVCaptureSession *)captureSession {
    if (!_captureSession) {
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

        if ([device lockForConfiguration:nil]) {
            //设置帧率
            device.activeVideoMinFrameDuration = CMTimeMake(2, 3);
        }
        AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput
                                              deviceInputWithDevice:device  error:nil];

        _captureSession = [[AVCaptureSession alloc] init];
        [_captureSession addInput:captureInput];
        [_captureSession addOutput:self.captureOutput];
    }

    return _captureSession;
}

- (AVCaptureVideoPreviewLayer *)prevLayer {
    if (!_prevLayer) {
        _prevLayer = [AVCaptureVideoPreviewLayer
                          layerWithSession:self.captureSession];
        _prevLayer.frame = [self rectForPreviewLayer];
        _prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    }

    return _prevLayer;
}

 如从缓冲区读取照片时,

- (void)captureOutput:(AVCaptureOutput *)captureOutput 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);

    //由于这段代码中,设备是home在下进行录制,所以此处在生成image时,指定了方向
    UIImage *image = [UIImage imageWithCGImage:newImage scale:1.0
                                      orientation:UIImageOrientationRight];

    CGImageRelease(newImage);

    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
}

上面只是正常从缓冲区获取到了图片,设置了正常显示的方向,如做矩形检测或人脸检测的时候,由于image的CGImage属性没有响应的调整方向,所以检测的时候可能会出现point转换的问题。为避免point转换这样比较繁琐的运算,所以可以在生成image的时候,调整好image避免后续的转换等问题

如在

        UIImage *image = [UIImage imageWithCGImage:newImage scale:1.0
                                      orientation:UIImageOrientationRight];
//此行保证image的imageOrientation为UIImageOrientationUp
        image = [image normalImage];
- (UIImage *)normalImage {

    if (self.imageOrientation == UIImageOrientationUp) return self;

    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    [self drawInRect:(CGRect){0, 0, self.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

通过以上方法,解决矩形检测、人脸识别时,point转换问题。

此为图片方向及检测的问题解决方法,视频暂未实践

转载于:https://my.oschina.net/u/1432769/blog/742152

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值