iOS自定义相机
我们选择拍照的时候,系统提供了一个UIImagePickerController,但是功能太弱,很多时候我们不得不自己实现拍照等。
在iOS里面系统提供一个AVFoundation的库,供用户使用相机,图片,音频,视频等一系列多媒体api。
做自定义相机大致如下几个步骤:
在view上添加一个AVCaptureVideoPreviewLayer,将输出图像预览在layer上
初始化一个AVCaptureSession,并且赋值给layer,给AVCaptureSession添加AVCaptureDeviceInput和AVCaptureDeviceOutput,设置捕捉的对象为setSessionPreset:AVCaptureSessionPresetPhoto
点击拍照时候,使用如下获取捕捉到的图片
[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {}
这里给出一个最简单的demo示例:(略)
上述只是实现了拍照的功能,其中我们很可能还需要许多其他功能,比如:闪光灯,摄像头切换等等。
摄像头切换:
1.判断是否支持多相机模式:
[[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count] > 1 ? YES : NO;
2.判断当前摄像头是前后:
AVCaptureDevicePosition position = _videoInput.device.position;
if (position == AVCaptureDevicePositionBack)
if (position == AVCaptureDevicePositionFront)
3.将新的摄像头输入设备放入,并且生效配置:
newVideoInput = [[AVCaptureDeviceInput alloc]initWithDevice:[self frontCamera] error:&error];
[_captureSession beginConfiguration];
[_captureSession removeInput:_videoInput];
if ([_captureSession canAddInput:newVideoInput]) {
[_captureSession addInput:newVideoInput];
_videoInput = newVideoInput;
}else{
[_captureSession addInput:_videoInput];
}
[_captureSession commitConfiguration];
同理:闪关灯,白平衡等有类似api设置
在相机输出图片后,我们可能需要对图片进行处理。
我这里需要用户对图片进行区域马赛克,我参考了in的做法(不一定相同).用一张png图片和点击坐标的颜色值进行组合,最后在layer上加入sublayer。
注:滤镜可在coreimage库里面做,这里我不涉及。
CGPoint p = [[touches anyObject] locationInView:self];
unsigned char pixel[4] = {0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextTranslateCTM(context, -point.x, -point.y);
[self.layer renderInContext:context];
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
UIColor *color = [UIColor colorWithRed:pixel[0]/255.0 green:pixel[1]/255.0 blue:pixel[2]/255.0 alpha:pixel[3]/255.0];
self.viewImage.backgroundColor = color;
CALayer *layer = [[CALayer alloc]init];
layer.frame = rect;
layer.contents = (id)[[UIImage imageNamed:@"camera_masico_icon"] tintImageWithColor:color].CGImage;
[self.layer addSublayer:layer];
该demo我放在Github上面:点击这里