2013第一篇,大家新年快樂!感謝一直關注我部落格的同學們,有你們的支援我才有動力越做越好!有陣子沒寫部落格了,因為前陣子著實比較忙,沒時間整理,今天主要實現一個小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部分代碼如下:
#import <Foundation/Foundation.h>@protocol PassImageDelegate <NSObject>-(void)passImage:(UIImage *)image;@end
CaptureViewController.h部分關鍵代碼,主要是初始化截取介面,截取成功後的處理等:
- (void)viewDidLoad{ [super viewDidLoad]; //添加導覽列和完成按鈕 UINavigationBar *naviBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; [self.view addSubview:naviBar]; UINavigationItem *naviItem = [[UINavigationItem alloc] initWithTitle:@"圖片裁剪"]; [naviBar pushNavigationItem:naviItem animated:YES]; //儲存按鈕 UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(saveButton)]; naviItem.rightBarButtonItem = doneItem; //image為上一個介面傳過來的圖片資源 editorView = [[AGSimpleImageEditorView alloc] initWithImage:self.image]; editorView.frame = CGRectMake(0, 0, self.view.frame.size.width , self.view.frame.size.width); editorView.center = self.view.center; //外邊框的寬度及顏色 editorView.borderWidth = 1.f; editorView.borderColor = [UIColor blackColor]; //截取框的寬度及顏色 editorView.ratioViewBorderWidth = 5.f; editorView.ratioViewBorderColor = [UIColor orangeColor]; //截取比例,我這裡按正方形1:1截取(可以寫成 3./2. 16./9. 4./3.) editorView.ratio = 1; [self.view addSubview:editorView];}//完成截取-(void)saveButton{ //output為截取後的圖片,UIImage類型 UIImage *resultImage = editorView.output; //通過代理回傳給上一個介面顯示 [self.delegate passImage:resultImage]; [self dismissModalViewControllerAnimated:YES];}
3.主介面開啟選項列表並選擇拍照或是從相簿選擇圖片代碼:
//彈出選項列表選擇圖片來源- (IBAction)choseButtonClicked:(id)sender { UIActionSheet *chooseImageSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Camera",@"Photo library", nil]; [chooseImageSheet showInView:self.view];}#pragma mark UIActionSheetDelegate Method-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ UIImagePickerController * picker = [[UIImagePickerController alloc] init]; picker.delegate = self; switch (buttonIndex) { case 0://Take picture if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { picker.sourceType = UIImagePickerControllerSourceTypeCamera; }else{ NSLog(@"模擬器無法開啟相機"); } [self presentModalViewController:picker animated:YES]; break; case 1://From album picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self presentModalViewController:picker animated:YES]; break; default: break; }}
拍照或選擇圖片後的回調方法:
#pragma 拍照選擇照片協議方法-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ [UIApplication sharedApplication].statusBarHidden = NO; NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; NSData *data; if ([mediaType isEqualToString:@"public.image"]){ //切忌不可直接使用originImage,因為這是沒有經過格式化的圖片資料,可能會導致選擇的圖片顛倒或是失真等現象的發生,從UIImagePickerControllerOriginalImage中的Origin可以看出,很原始,哈哈 UIImage *originImage = [info objectForKey:UIImagePickerControllerOriginalImage]; //圖片壓縮,因為原圖都是很大的,不必要傳原圖 UIImage *scaleImage = [self scaleImage:originImage toScale:0.3]; //以下這兩步都是比較耗時的操作,最好開一個HUD提示使用者,這樣體驗會好些,不至於阻塞介面 if (UIImagePNGRepresentation(scaleImage) == nil) { //將圖片轉換為JPG格式的位元據 data = UIImageJPEGRepresentation(scaleImage, 1); } else { //將圖片轉換為PNG格式的位元據 data = UIImagePNGRepresentation(scaleImage); } //將位元據產生UIImage UIImage *image = [UIImage imageWithData:data]; //將圖片傳遞給截取介面進行截取並設定回調方法(協議) CaptureViewController *captureView = [[CaptureViewController alloc] init]; captureView.delegate = self; captureView.image = image; //隱藏UIImagePickerController本身的導覽列 picker.navigationBar.hidden = YES; [picker pushViewController:captureView animated:YES]; }}
回調方法,顯示截取後的圖片
#pragma mark - 圖片回傳協議方法-(void)passImage:(UIImage *)image{ //將截取的圖片顯示在主介面 imageView.image = image;}
最後就是一段縮放圖片的方法:
#pragma mark- 縮放圖片-(UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize{ UIGraphicsBeginImageContext(CGSizeMake(image.size.width*scaleSize,image.size.height*scaleSize)); [image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height *scaleSize)]; UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return scaledImage;}
完成後到真機上運行,效果如下:
拍照後選擇圖片後進入到裁剪介面,裁剪完成後顯示裁剪結果:
加入我們的QQ群或公眾帳號請查看:Ryan's
zone公眾帳號及QQ群
覺得文章對你有用,歡迎關注我的新浪微博和我交流:@唐韌_Ryan
工程下載:Demo源碼