//TKImageView:[https://github.com/3tinkers/TKImageView](https://github.com/3tinkers/TKImageView)
#import
@protocolCameraDelegate
- (void)CameraTakePhoto:(UIImage *)image;
@end
@interfaceCameraViewController : UIViewController
@property(nonatomic,weak)id delegate;
@end
#import "CameraViewController.h"
#import
#import
#import "ClipViewController.h"
#define KWIDTH [UIScreen mainScreen].bounds.size.width
#define KHEIGHT [UIScreen mainScreen].bounds.size.height
@interfaceCameraViewController ()
/**
* AVCaptureSession对象来执行输入设备和输出设备之间的数据传递
*/
@property(nonatomic,strong) AVCaptureSession* session;
/**
* 输入设备
*/
@property(nonatomic,strong) AVCaptureDeviceInput* videoInput;
/**
* 照片输出流
*/
@property(nonatomic,strong) AVCaptureStillImageOutput* stillImageOutput;
/**
* 预览图层
*/
@property(nonatomic,strong) AVCaptureVideoPreviewLayer* previewLayer;
/**
* 记录开始的缩放比例
*/
@property(nonatomic,assign)CGFloat beginGestureScale;
/**
* 最后的缩放比例
*/
@property(nonatomic,assign)CGFloat effectiveScale;
@property(nonatomic,strong) AVCaptureConnection *stillImageConnection;
@property (nonatomic, strong) NSData *jpegData;
@property(nonatomic,assign) CFDictionaryRef attachments;
@property (nonatomic, strong) UIView *toolView;
@property(nonatomic,strong) UIView *editorView;
@property(nonatomic,strong) UIImagePickerController *imgPicker;
@end
@implementationCameraViewController
- (void)viewDidLoad {
[superviewDidLoad];
// [self CreatedCamera];
// [self selectImageFrromCamera];
[selfinitAVCaptureSession];
[selfsetUpGesture];
[selfcreatedTool];
}
- (void)createdTool
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, KWIDTH,64)];
headerView.backgroundColor = [UIColor blackColor];
headerView.alpha =0.8;
[self.view addSubview:headerView];
UILabel *titleLable = [[UILabel alloc] initWithFrame:CGRectMake((KWIDTH -100)/2.0,12,100,40)];
titleLable.text =@"拍照";
[titleLable setTextColor:[UIColor whiteColor]];
titleLable.textAlignment = NSTextAlignmentCenter;
[headerView addSubview:titleLable];
UIButton *headerBtn = [UIButton buttonWithType:UIButtonTypeCustom];
headerBtn.frame = CGRectMake(KWIDTH - 80-15,12,80,40);
[headerBtn setTitle:@"取消"forState:UIControlStateNormal];
[headerBtn addTarget:selfaction:@selector(cancleCamera) forControlEvents:UIControlEventTouchUpInside];
[headerView addSubview:headerBtn];
[self.navigationController.navigationBar.subviews.lastObject setHidden:YES];
self.toolView = [[UIView alloc] initWithFrame:CGRectMake(0, KHEIGHT -120, KWIDTH,120)];
self.toolView.backgroundColor = [UIColor blackColor];
self.toolView.alpha =0.8;
[self.view addSubview:self.toolView];
UIButton *cameraBtn = [UIButton buttonWithType:UIButtonTypeCustom];
cameraBtn.frame = CGRectMake((KWIDTH -50)/2.0, (120-50)/2.0,50,50);
[cameraBtn setImage:[UIImage imageNamed:@"takePhoto"] forState:UIControlStateNormal];
[cameraBtn addTarget:selfaction:@selector(takePhotoButtonClick) forControlEvents:UIControlEventTouchUpInside];
[self.toolView addSubview:cameraBtn];
UIButton *photoBtn = [UIButton buttonWithType:UIButtonTypeCustom];
photoBtn.frame = CGRectMake(((KWIDTH /2.0) -30)/2.0, ((120) -30)/2.0,30,30);
[photoBtn addTarget:selfaction:@selector(openCamera) forControlEvents:UIControlEventTouchUpInside];
[photoBtn setImage:[UIImage imageNamed:@"cameraPhoto"] forState:UIControlStateNormal];
[self.toolView addSubview:photoBtn];
UIButton *lampBtn = [UIButton buttonWithType:UIButtonTypeCustom];
lampBtn.frame = CGRectMake(((KWIDTH /2.0) -30)/2.0+ (KWIDTH /2.0), ((120) -30)/2.0,30,30);
[lampBtn setImage:[UIImage imageNamed:@"openFlish"] forState:UIControlStateSelected];
[lampBtn setImage:[UIImage imageNamed:@"closeFlish"] forState:UIControlStateNormal];
[lampBtn addTarget:selfaction:@selector(flashButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.toolView addSubview:lampBtn];
}
- (void)initAVCaptureSession{
self.session = [[AVCaptureSession alloc] init];
NSError *error;
self.effectiveScale =1.0;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//更改这个设置的时候必须先锁定设备,修改完后再解锁,否则崩溃
[device lockForConfiguration:nil];
[device unlockForConfiguration];
self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error];
if(error) {
NSLog(@"%@",error);
}
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
//输出设置。AVVideoCodecJPEG 输出jpeg格式图片
NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
[self.stillImageOutput setOutputSettings:outputSettings];
if([self.session canAddInput:self.videoInput]) {
[self.session addInput:self.videoInput];
}
if([self.session canAddOutput:self.stillImageOutput]) {
[self.session addOutput:self.stillImageOutput];
}
//初始化预览图层
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
[self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.previewLayer.frame = CGRectMake(0,0,KWIDTH, KHEIGHT);
self.view.layer.masksToBounds =YES;
[self.view.layer addSublayer:self.previewLayer];
[selfresetFocusAndExposureModes];
}
- (void)viewWillAppear:(BOOL)animated{
[superviewWillAppear:YES];
if(self.session) {
[self.session startRunning];
}
}
- (void)viewDidDisappear:(BOOL)animated{
[superviewDidDisappear:YES];
if(self.session) {
[self.session stopRunning];
}
}
//自动聚焦、曝光
- (BOOL)resetFocusAndExposureModes{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureExposureMode exposureMode = AVCaptureExposureModeContinuousAutoExposure;
AVCaptureFocusMode focusMode = AVCaptureFocusModeContinuousAutoFocus;
BOOLcanResetFocus = [device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode];
BOOLcanResetExposure = [device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode];
CGPoint centerPoint = CGPointMake(0.5f,0.5f);
NSError *error;
if([device lockForConfiguration:&error]) {
if(canResetFocus) {
device.focusMode = focusMode;
device.focusPointOfInterest = centerPoint;
}
if(canResetExposure) {
device.exposureMode = exposureMode;
device.exposurePointOfInterest = centerPoint;
}
[device unlockForConfiguration];
returnYES;
}
else{
NSLog(@"%@", error);
returnNO;
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = touches.anyObject;
CGPoint point = [touch locationInView:self.view];
[selffocusAtPoint:point];
}
//聚焦
- (void)focusAtPoint:(CGPoint)point {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if([selfcameraSupportsTapToFocus] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
NSError *error;
if([device lockForConfiguration:&error]) {
device.focusPointOfInterest = point;
device.focusMode = AVCaptureFocusModeAutoFocus;
[device unlockForConfiguration];
}
else{
NSLog(@"%@", error);
}
}
}
- (BOOL)cameraSupportsTapToFocus {
return[[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] isFocusPointOfInterestSupported];
}
//获取设备方向
-(AVCaptureVideoOrientation)avOrientationForDeviceOrientation:(UIDeviceOrientation)deviceOrientation
{
AVCaptureVideoOrientation result = (AVCaptureVideoOrientation)deviceOrientation;
if( deviceOrientation == UIDeviceOrientationLandscapeLeft )
result = AVCaptureVideoOrientationLandscapeRight;
elseif( deviceOrientation == UIDeviceOrientationLandscapeRight )
result = AVCaptureVideoOrientationLandscapeLeft;
returnresult;
}
//照相
- (void)takePhotoButtonClick {
_stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];
AVCaptureVideoOrientation avcaptureOrientation = [selfavOrientationForDeviceOrientation:curDeviceOrientation];
[_stillImageConnection setVideoOrientation:avcaptureOrientation];
[_stillImageConnection setVideoScaleAndCropFactor:self.effectiveScale];
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:_stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
NSData *jpegData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
[selfjumpImageView:jpegData];
}];
}
//拍照之后调到相片详情页面
-(void)jumpImageView:(NSData*)data{
ClipViewController *viewController = [[ClipViewController alloc] init];
UIImage *image = [UIImage imageWithData:data];
viewController.image = image;
viewController.picker = _imgPicker;
viewController.controller =self;
viewController.delegate =self;
viewController.isTakePhoto =YES;
[selfpresentViewController:viewController animated:NOcompletion:nil];
}
- (void)cancleCamera
{
[selfdismissViewControllerAnimated:YEScompletion:nil];
}
#pragma mark -- TakePhotoDelegate
- (void)takePhoto:(UIImage *)image
{
if(self.delegate && [self.delegate respondsToSelector:@selector(CameraTakePhoto:)]) {
[selfdismissViewControllerAnimated:YEScompletion:nil];
[self.delegate CameraTakePhoto:image];
}
}
//打开闪光灯
- (void)flashButtonClick:(UIButton *)sender {
sender.selected = !sender.selected;
if(sender.isSelected ==YES) {//打开闪光灯
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error =nil;
if([captureDevice hasTorch]) {
BOOLlocked = [captureDevice lockForConfiguration:&error];
if(locked) {
captureDevice.torchMode = AVCaptureTorchModeOn;
[captureDevice unlockForConfiguration];
}
}
}else{//关闭闪光灯
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if([device hasTorch]) {
[device lockForConfiguration:nil];
[device setTorchMode: AVCaptureTorchModeOff];
[device unlockForConfiguration];
}
}
}
//添加手势代理
- (void)setUpGesture
{
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:selfaction:@selector(handlePinchGesture:)];
pinch.delegate =self;
[self.view addGestureRecognizer:pinch];
}
//缩放手势 用于调整焦距
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer{
BOOLallTouchesAreOnThePreviewLayer =YES;
NSUInteger numTouches = [recognizer numberOfTouches], i;
for( i =0; i < numTouches; ++i ) {
CGPoint location = [recognizer locationOfTouch:i inView:self.view];
CGPoint convertedLocation = [self.previewLayer convertPoint:location fromLayer:self.previewLayer.superlayer];
if( ! [self.previewLayer containsPoint:convertedLocation] ) {
allTouchesAreOnThePreviewLayer =NO;
break;
}
}
if( allTouchesAreOnThePreviewLayer ) {
self.effectiveScale =self.beginGestureScale * recognizer.scale;
if(self.effectiveScale <1.0){
self.effectiveScale =1.0;
}
NSLog(@"%f-------------->%f------------recognizerScale%f",self.effectiveScale,self.beginGestureScale,recognizer.scale);
CGFloat maxScaleAndCropFactor = [[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] videoMaxScaleAndCropFactor];
NSLog(@"%f",maxScaleAndCropFactor);
if(self.effectiveScale > maxScaleAndCropFactor)
self.effectiveScale = maxScaleAndCropFactor;
[CATransaction begin];
[CATransaction setAnimationDuration:.025];
[self.previewLayer setAffineTransform:CGAffineTransformMakeScale(self.effectiveScale,self.effectiveScale)];
[CATransaction commit];
}
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if( [gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] ) {
self.beginGestureScale =self.effectiveScale;
}
return YES;
}
//打开相册
- (void)openCamera
{
[selfopenImagePickerControllerWithType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
}
/// 打开ImagePickerController的方法
- (void)openImagePickerControllerWithType:(UIImagePickerControllerSourceType)type
{
// 设备不可用 直接返回
if(![UIImagePickerController isSourceTypeAvailable:type])return;
_imgPicker = [[UIImagePickerController alloc] init];
_imgPicker.sourceType = type;
_imgPicker.delegate =self;
_imgPicker.allowsEditing =NO;
[selfpresentViewController:_imgPicker animated:YEScompletion:nil];
}
#pragma mark - UINavigationControllerDelegate, UIImagePickerControllerDelegate
// 选择照片之后
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = info[UIImagePickerControllerOriginalImage];
[selfcropImage:image];
}
- (void)cropImage: (UIImage *)image {
ClipViewController *viewController = [[ClipViewController alloc] init];
viewController.image = image;
viewController.picker = _imgPicker;
viewController.controller =self;
viewController.delegate =self;
viewController.isTakePhoto =NO;
[_imgPicker presentViewController:viewController animated:NOcompletion:nil];
}
#pragma mark -- ClipPhotoDelegate
- (void)clipPhoto:(UIImage *)image
{
if(self.delegate && [self.delegate respondsToSelector:@selector(CameraTakePhoto:)]) {
[selfdismissViewControllerAnimated:YEScompletion:nil];
[self.delegate CameraTakePhoto:image];
}
}
@end
------------------------
#import
@protocolClipPhotoDelegate
- (void)clipPhoto:(UIImage *)image;
@end
@interfaceClipViewController : UIViewController
@property (strong, nonatomic) UIImage *image;
@property(nonatomic,strong) UIImagePickerController *picker;
@property(nonatomic,strong) UIViewController *controller;
@property(nonatomic,weak)id delegate;
@property (nonatomic, assign) BOOL isTakePhoto;
@end
#import "ClipViewController.h"
#import "TKImageView.h"
#define SelfWidth [UIScreen mainScreen].bounds.size.width
#define SelfHeight [UIScreen mainScreen].bounds.size.height
@interfaceClipViewController ()
@property (nonatomic, assign) BOOL isClip;
@property(nonatomic,strong) TKImageView *tkImageView;
@end
@implementationClipViewController
- (void)viewDidLoad {
[superviewDidLoad];
[selfcreatedTkImageView];
[selfcreatedTool];
}
- (void)createdTkImageView
{
_tkImageView = [[TKImageView alloc] initWithFrame:CGRectMake(0,0, SelfWidth, SelfHeight -120)];
[self.view addSubview:_tkImageView];
//需要进行裁剪的图片对象
_tkImageView.toCropImage = _image;
//是否显示中间线
_tkImageView.showMidLines =YES;
//是否需要支持缩放裁剪
_tkImageView.needScaleCrop =YES;
//是否显示九宫格交叉线
_tkImageView.showCrossLines =YES;
_tkImageView.cornerBorderInImage =NO;
_tkImageView.cropAreaCornerWidth =44;
_tkImageView.cropAreaCornerHeight =44;
_tkImageView.minSpace =30;
_tkImageView.cropAreaCornerLineColor = [UIColor whiteColor];
_tkImageView.cropAreaBorderLineColor = [UIColor whiteColor];
_tkImageView.cropAreaCornerLineWidth =6;
_tkImageView.cropAreaBorderLineWidth =1;
_tkImageView.cropAreaMidLineWidth =20;
_tkImageView.cropAreaMidLineHeight =6;
_tkImageView.cropAreaMidLineColor = [UIColor whiteColor];
_tkImageView.cropAreaCrossLineColor = [UIColor whiteColor];
_tkImageView.cropAreaCrossLineWidth =0.5;
_tkImageView.initialScaleFactor =.8f;
_tkImageView.cropAspectRatio =0;
_tkImageView.maskColor = [UIColor clearColor];
self.isClip =NO;
}
- (void)createdTool
{
UIView *editorView = [[UIView alloc] initWithFrame:CGRectMake(0, SelfHeight -120, SelfWidth,120)];
editorView.backgroundColor = [UIColor blackColor];
editorView.alpha =0.8;
[self.view addSubview:editorView];
UIButton *cancleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
cancleBtn.frame = CGRectMake(((SelfWidth /3.0) -50)/2.0, (120-50)/2.0,50,50);
[cancleBtn setImage:[UIImage imageNamed:@"canclePhoto"] forState:UIControlStateNormal];
[cancleBtn addTarget:selfaction:@selector(back) forControlEvents:UIControlEventTouchUpInside];
[editorView addSubview:cancleBtn];
UIButton *clipBtn = [UIButton buttonWithType:UIButtonTypeCustom];
clipBtn.frame = CGRectMake(((SelfWidth) -50)/2.0, (120-50)/2.0,50,50);
[clipBtn setImage:[UIImage imageNamed:@"clipPhoto"] forState:UIControlStateNormal];
[clipBtn setImage:[UIImage imageNamed:@"backPhoto"] forState:UIControlStateSelected];
[clipBtn addTarget:selfaction:@selector(clip:) forControlEvents:UIControlEventTouchUpInside];
[editorView addSubview:clipBtn];
UIButton *sureBtn = [UIButton buttonWithType:UIButtonTypeCustom];
sureBtn.frame = CGRectMake(((SelfWidth/3.0) -50)/2.0+ (SelfWidth *2.0/3.0), (120-50)/2.0,50,50);
[sureBtn setImage:[UIImage imageNamed:@"surePhoto"] forState:UIControlStateNormal];
[sureBtn addTarget:selfaction:@selector(sure) forControlEvents:UIControlEventTouchUpInside];
[editorView addSubview:sureBtn];
}
- (void)back{
[selfdismissViewControllerAnimated:YEScompletion:nil];
}
- (void)clip:(UIButton *)btn{
btn.selected = !btn.selected;
self.isClip = btn.selected;
if(btn.selected ==YES) {
_tkImageView.toCropImage = [_tkImageView currentCroppedImage];
}else{
_tkImageView.toCropImage = _image;
}
}
- (void)sure{
//裁剪
if(self.isClip ==YES) {
UIImage *image = [_tkImageView currentCroppedImage];
if(self.isTakePhoto) {
//将图片存储到相册
UIImageWriteToSavedPhotosAlbum(image,self,nil,nil);
}
if(self.delegate && [self.delegate respondsToSelector:@selector(clipPhoto:)]) {
[self.delegate clipPhoto:image];
}
}else{
if(self.delegate && [self.delegate respondsToSelector:@selector(clipPhoto:)]) {
[self.delegate clipPhoto:self.image];
}
if(self.isTakePhoto) {
//将图片存储到相册
UIImageWriteToSavedPhotosAlbum(self.image,self,nil,nil);
}
}
[selfdismissViewControllerAnimated:YEScompletion:nil];
[self.picker dismissViewControllerAnimated:YEScompletion:nil];
[self.controller dismissViewControllerAnimated:YEScompletion:nil];
}
- (void)didReceiveMemoryWarning {
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
-------------
#import
typedefNS_ENUM(NSInteger, TKCropAreaCornerStyle) {
TKCropAreaCornerStyleRightAngle,
TKCropAreaCornerStyleCircle
};
@interfaceTKImageView : UIView
@property(strong,nonatomic) UIImage *toCropImage;
@property (assign, nonatomic) BOOL needScaleCrop;
@property (assign, nonatomic) BOOL showMidLines;
@property (assign, nonatomic) BOOL showCrossLines;
@property(assign,nonatomic) CGFloat cropAspectRatio;
@property(strong,nonatomic) UIColor *cropAreaBorderLineColor;
@property(assign,nonatomic) CGFloat cropAreaBorderLineWidth;
@property(strong,nonatomic) UIColor *cropAreaCornerLineColor;
@property(assign,nonatomic) CGFloat cropAreaCornerLineWidth;
@property(assign,nonatomic) CGFloat cropAreaCornerWidth;
@property(assign,nonatomic) CGFloat cropAreaCornerHeight;
@property (assign, nonatomic) CGFloat minSpace;
@property(assign,nonatomic) CGFloat cropAreaCrossLineWidth;
@property(strong,nonatomic) UIColor *cropAreaCrossLineColor;
@property(assign,nonatomic) CGFloat cropAreaMidLineWidth;
@property(assign,nonatomic) CGFloat cropAreaMidLineHeight;
@property(strong,nonatomic) UIColor *cropAreaMidLineColor;
@property(strong,nonatomic) UIColor *maskColor;
@property (assign, nonatomic) BOOL cornerBorderInImage;
@property(assign,nonatomic) CGFloat initialScaleFactor;
- (UIImage *)currentCroppedImage;
@end
网友评论