天天看點

iOS拍照、從相冊選圖并對圖檔進行裁剪

2013第一篇,大家新年快樂!感謝一直關注我部落格的同學們,有你們的支援我才有動力越做越好!

iOS拍照、從相冊選圖并對圖檔進行裁剪

有陣子沒寫部落格了,因為前陣子着實比較忙,沒時間整理,今天主要實作一個小Demo,我們知道在Instagram或Path上,頭像都是正方形的,得到這種頭像圖檔肯定要對原圖進行截取,今天抽時間整理了下,先記錄如下!早前寫過一篇《IOS學習筆記22—檔案操作(NSFileManager)結合相冊小例子》,随着iOS SDK的更新,拍照及從相冊選取圖檔的實作過程發生了一點小變化,比如UIImagePickerControllerDelegate的回調方法。現結合一個Demo簡要介紹其實作過程。首先,裁剪圖檔的功能借助了Github上的項目AGSimpleImageEditorView。不多說,一步步的看Demo的實作過程吧:

1.下載下傳Github上這個項目工程到本地并将其拖入到自己的工程中(前提是你已經建立了工程

iOS拍照、從相冊選圖并對圖檔進行裁剪

),由于AGSimpleImageEditorView不支援ARC,是以還要做相應的配置,設定編譯器标簽-fno-objc-arc:

iOS拍照、從相冊選圖并對圖檔進行裁剪

另外,由于使用到圖形處理和圖檔處理,是以還要另外導入兩個庫,如下圖

iOS拍照、從相冊選圖并對圖檔進行裁剪

完成後,按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.     UINavigationItem *naviItem = [[UINavigationItem alloc] initWithTitle:@"圖檔裁剪"];  
  8.     [naviBar pushNavigationItem:naviItem animated:YES];  
  9.     //儲存按鈕  
  10.     UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:@"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.     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.     switch (buttonIndex) {  
  12.         case 0://Take picture  
  13.             if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {  
  14.                 picker.sourceType = UIImagePickerControllerSourceTypeCamera;  
  15.             }else{  
  16.                 NSLog(@"模拟器無法打開相機");  
  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. }  

完成後到真機上運作,效果如下:

iOS拍照、從相冊選圖并對圖檔進行裁剪
iOS拍照、從相冊選圖并對圖檔進行裁剪

拍照後選擇圖檔後進入到裁剪界面,裁剪完成後顯示裁剪結果:

iOS拍照、從相冊選圖并對圖檔進行裁剪
iOS拍照、從相冊選圖并對圖檔進行裁剪

加入我們的QQ群或微信公衆賬号請檢視: Ryan's zone公衆賬号及QQ群

覺得文章對你有用,歡迎關注我的新浪微網誌和我交流:@唐韌_Ryan

繼續閱讀