IOS学习笔记39——拍照、从相册选图并对图片进行裁剪

今天主要实现一个小Demo,我们知道在Instagram或Path上,头像都是正方形的,得到这种头像图片肯定要对原图进行截取,今天抽时间整理了下,先记录如下!早前写过一篇《IOS学习笔记22—文件操作(NSFileManager)结合相册小例子》,随着iOS SDK的升级,拍照及从相册选取图片的实现过程发生了一点小变化,比如UIImagePickerControllerDelegate的回调方法。现结合一个Demo简要介绍其实现过程。首先,裁剪图片的功能借助了Github上的项目AGSimpleImageEditorView。不多说,一步步的看Demo的实现过程吧:


1.下载Github上这个项目工程到本地并将其拖入到自己的工程中(前提是你已经建立了工程 

),由于AGSimpleImageEditorView不支持ARC,所以还要做相应的配置,设置编译器标签-fno-objc-arc:



另外,由于使用到图形处理和图片处理,所以还要另外导入两个库,如下图


完成后,按command+B编译试试,如果没问题,说明工程集成成功了,下面就可以开始编码了,如果不成功,检查一下错误来源,上述步骤是否完整。


代码部分:以下均为关键代码,具体细节没有列举,注释写的非常详细,就不赘述了


2.新建PassImageDelegate协议作为在展示界面和截取界面间传值的代理(这个demo用到两种传值方式,不是很了解的可以参考一下《IOS学习笔记30—两个ViewController间传值(一)》),新建CaptureViewController作为截取图片功能的模块。PassImageDelegate部分代码如下:

  1. #import

  2. @protocol PassImageDelegate

  3. -(void)passImage:(UIImage *)image;

  4. @end
复制代码
CaptureViewController.h部分关键代码,主要是初始化截取界面,截取成功后的处理等:
  1. - (void)viewDidLoad
  2. {
  3.     [super viewDidLoad];
  4.     
  5.     //添加导航栏和完成按钮
  6.     UINavigationBar *naviBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
  7.     [self.view addSubview:naviBar];
  8.     
  9.     UINavigationItem *naviItem = [[UINavigationItem alloc] initWithTitle:@"图片裁剪"];
  10.     [naviBar pushNavigationItem:naviItem animated:YES];
  11.     
  12.     //保存按钮
  13.     UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(saveButton)];
  14.     naviItem.rightBarButtonItem = doneItem;
  15.     
  16.     //image为上一个界面传过来的图片资源
  17.     editorView = [[AGSimpleImageEditorView alloc] initWithImage:self.image];
  18.     editorView.frame = CGRectMake(0, 0, self.view.frame.size.width ,  self.view.frame.size.width);
  19.     editorView.center = self.view.center;
  20.     
  21.     //外边框的宽度及颜色
  22.     editorView.borderWidth = 1.f;
  23.     editorView.borderColor = [UIColor blackColor];
  24.     
  25.     //截取框的宽度及颜色
  26.     editorView.ratioViewBorderWidth = 5.f;
  27.     editorView.ratioViewBorderColor = [UIColor orangeColor];
  28.     
  29.     //截取比例,我这里按正方形1:1截取(可以写成 3./2. 16./9. 4./3.)
  30.     editorView.ratio = 1;
  31.     
  32.     [self.view addSubview:editorView];
  33. }

  34. //完成截取
  35. -(void)saveButton
  36. {
  37.     //output为截取后的图片,UIImage类型
  38.     UIImage *resultImage = editorView.output;
  39.     
  40.     //通过代理回传给上一个界面显示
  41.     [self.delegate passImage:resultImage];
  42.     
  43.     [self dismissModalViewControllerAnimated:YES];
  44. }
复制代码
3.主界面打开选项列表并选择拍照或是从相册选择图片代码:
  1. //弹出选项列表选择图片来源
  2. - (IBAction)choseButtonClicked:(id)sender {
  3.     UIActionSheet *chooseImageSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Camera",@"Photo library", nil];
  4.     [chooseImageSheet showInView:self.view];
  5. }

  6. #pragma mark UIActionSheetDelegate Method
  7. -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
  8. {
  9.     UIImagePickerController * picker = [[UIImagePickerController alloc] init];
  10.     picker.delegate = self;
  11.     
  12.     switch (buttonIndex) {
  13.         case 0://Take picture
  14.             
  15.             if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  16.                 picker.sourceType = UIImagePickerControllerSourceTypeCamera;
  17.                 
  18.             }else{
  19.                 NSLog(@"模拟器无法打开相机");
  20.             }
  21.             [self presentModalViewController:picker animated:YES];
  22.             break;
  23.             
  24.         case 1://From album
  25.             picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  26.             [self presentModalViewController:picker animated:YES];
  27.             break;
  28.             
  29.         default:
  30.             
  31.             break;
  32.     }
  33. }
复制代码
拍照或选择图片后的回调方法:
  1. #pragma 拍照选择照片协议方法
  2. -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
  3. {
  4.     
  5.     [UIApplication sharedApplication].statusBarHidden = NO;
  6.     
  7.     NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
  8.     
  9.     NSData *data;
  10.     
  11.     if ([mediaType isEqualToString:@"public.image"]){
  12.         
  13.         //切忌不可直接使用originImage,因为这是没有经过格式化的图片数据,可能会导致选择的图片颠倒或是失真等现象的发生,从UIImagePickerControllerOriginalImage中的Origin可以看出,很原始,哈哈
  14.         UIImage *originImage = [info objectForKey:UIImagePickerControllerOriginalImage];
  15.         
  16.         //图片压缩,因为原图都是很大的,不必要传原图
  17.         UIImage *scaleImage = [self scaleImage:originImage toScale:0.3];
  18.         
  19.         //以下这两步都是比较耗时的操作,最好开一个HUD提示用户,这样体验会好些,不至于阻塞界面
  20.         if (UIImagePNGRepresentation(scaleImage) == nil) {
  21.             //将图片转换为JPG格式的二进制数据
  22.             data = UIImageJPEGRepresentation(scaleImage, 1);
  23.         } else {
  24.             //将图片转换为PNG格式的二进制数据
  25.             data = UIImagePNGRepresentation(scaleImage);
  26.         }
  27.         
  28.         //将二进制数据生成UIImage
  29.         UIImage *image = [UIImage imageWithData:data];
  30.         
  31.         //将图片传递给截取界面进行截取并设置回调方法(协议)
  32.         CaptureViewController *captureView = [[CaptureViewController alloc] init];
  33.         captureView.delegate = self;
  34.         captureView.image = image;
  35.         //隐藏UIImagePickerController本身的导航栏
  36.         picker.navigationBar.hidden = YES;
  37.         [picker pushViewController:captureView animated:YES];
  38.         
  39.     }
  40. }
复制代码
回调方法,显示截取后的图片
  1. #pragma mark - 图片回传协议方法
  2. -(void)passImage:(UIImage *)image
  3. {
  4.     //将截取的图片显示在主界面
  5.     imageView.image = image;
  6. }
复制代码
最后就是一段缩放图片的方法:
  1. #pragma mark- 缩放图片
  2. -(UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize
  3. {
  4.     UIGraphicsBeginImageContext(CGSizeMake(image.size.width*scaleSize,image.size.height*scaleSize));
  5.     [image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height *scaleSize)];
  6.     UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
  7.     UIGraphicsEndImageContext();
  8.     return scaledImage;
  9. }
复制代码
完成后到真机上运行,效果如下:                            

拍照后选择图片后进入到裁剪界面,裁剪完成后显示裁剪结果:                           

你可能感兴趣的:(iOS)