0
点赞
收藏
分享

微信扫一扫

拍照、从相册选图并对图片进行裁剪


2013第一篇,大家新年快乐!感谢一直关注我博客的同学们,有你们的支持我才有动力越做越好!

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

 

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

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

拍照、从相册选图并对图片进行裁剪_#pragma

 

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

拍照、从相册选图并对图片进行裁剪_#pragma_02

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

 

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

 

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

 


[cpp]  ​​view plain​​​ ​​copy​​


  1. #import <Foundation/Foundation.h>

  2. @protocol PassImageDelegate <NSObject>

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

  4. @end


CaptureViewController.h部分关键代码,主要是初始化截取界面,截取成功后的处理等:

 

 


[cpp]  ​​view plain​​​ ​​copy​​


  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];

  4. //添加导航栏和完成按钮
  5. UINavigationBar *naviBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
  6. [self.view addSubview:naviBar];

  7. "图片裁剪"];
  8. [naviBar pushNavigationItem:naviItem animated:YES];

  9. //保存按钮
  10. "Done" style:UIBarButtonItemStylePlain target:self action:@selector(saveButton)];
  11. naviItem.rightBarButtonItem = doneItem;

  12. //image为上一个界面传过来的图片资源
  13. editorView = [[AGSimpleImageEditorView alloc] initWithImage:self.image];
  14. editorView.frame = CGRectMake(0, 0, self.view.frame.size.width ,  self.view.frame.size.width);
  15. editorView.center = self.view.center;

  16. //外边框的宽度及颜色
  17. editorView.borderWidth = 1.f;
  18. editorView.borderColor = [UIColor blackColor];

  19. //截取框的宽度及颜色
  20. editorView.ratioViewBorderWidth = 5.f;
  21. editorView.ratioViewBorderColor = [UIColor orangeColor];

  22. //截取比例,我这里按正方形1:1截取(可以写成 3./2. 16./9. 4./3.)
  23. editorView.ratio = 1;

  24. [self.view addSubview:editorView];
  25. }

  26. //完成截取
  27. -(void)saveButton
  28. {
  29. //output为截取后的图片,UIImage类型
  30. UIImage *resultImage = editorView.output;

  31. //通过代理回传给上一个界面显示
  32. [self.delegate passImage:resultImage];

  33. [self dismissModalViewControllerAnimated:YES];
  34. }


3.主界面打开选项列表并选择拍照或是从相册选择图片代码:

 

 


[cpp]  ​​view plain​​​ ​​copy​​


  1. //弹出选项列表选择图片来源
  2. - (IBAction)choseButtonClicked:(id)sender {
  3. "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. switch (buttonIndex) {
  12. case 0://Take picture

  13. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  14. picker.sourceType = UIImagePickerControllerSourceTypeCamera;

  15. else{
  16. "模拟器无法打开相机");
  17. }
  18. [self presentModalViewController:picker animated:YES];
  19. break;

  20. case 1://From album
  21. picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  22. [self presentModalViewController:picker animated:YES];
  23. break;

  24. default:

  25. break;
  26. }
  27. }


拍照或选择图片后的回调方法:

 

 


[cpp]  ​​view plain​​​ ​​copy​​


  1. #pragma 拍照选择照片协议方法
  2. -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
  3. {

  4. [UIApplication sharedApplication].statusBarHidden = NO;

  5. NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];

  6. NSData *data;

  7. if ([mediaType isEqualToString:@"public.image"]){

  8. //切忌不可直接使用originImage,因为这是没有经过格式化的图片数据,可能会导致选择的图片颠倒或是失真等现象的发生,从UIImagePickerControllerOriginalImage中的Origin可以看出,很原始,哈哈
  9. UIImage *originImage = [info objectForKey:UIImagePickerControllerOriginalImage];

  10. //图片压缩,因为原图都是很大的,不必要传原图
  11. UIImage *scaleImage = [self scaleImage:originImage toScale:0.3];

  12. //以下这两步都是比较耗时的操作,最好开一个HUD提示用户,这样体验会好些,不至于阻塞界面
  13. if (UIImagePNGRepresentation(scaleImage) == nil) {
  14. //将图片转换为JPG格式的二进制数据
  15. data = UIImageJPEGRepresentation(scaleImage, 1);
  16. else {
  17. //将图片转换为PNG格式的二进制数据
  18. data = UIImagePNGRepresentation(scaleImage);
  19. }

  20. //将二进制数据生成UIImage
  21. UIImage *image = [UIImage imageWithData:data];

  22. //将图片传递给截取界面进行截取并设置回调方法(协议)
  23. CaptureViewController *captureView = [[CaptureViewController alloc] init];
  24. captureView.delegate = self;
  25. captureView.image = image;
  26. //隐藏UIImagePickerController本身的导航栏
  27. picker.navigationBar.hidden = YES;
  28. [picker pushViewController:captureView animated:YES];

  29. }
  30. }


回调方法,显示截取后的图片

 

 


[cpp]  ​​view plain​​​ ​​copy​​


  1. #pragma mark - 图片回传协议方法
  2. -(void)passImage:(UIImage *)image
  3. {
  4. //将截取的图片显示在主界面
  5. imageView.image = image;
  6. }


最后就是一段缩放图片的方法:

 

 


[cpp]  ​​view plain​​​ ​​copy​​


  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. }


完成后到真机上运行,效果如下:

 

拍照、从相册选图并对图片进行裁剪_选择图片_03

                        

拍照、从相册选图并对图片进行裁剪_回调方法_04

 

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

拍照、从相册选图并对图片进行裁剪_回调方法_05

                        

拍照、从相册选图并对图片进行裁剪_回调方法_06

 

 


 

举报

相关推荐

0 条评论