6.自定義圖片剪下

weixin_34253539發表於2018-05-18

TKImageView:https://github.com/3tinkers/TKImageView 


6075426-a4ec8fea3973ee5f.png


#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

相關文章