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部分代碼如下:
[cpp] view plain copy
- #import <Foundation/Foundation.h>
- @protocol PassImageDelegate <NSObject>
- -(void)passImage:(UIImage *)image;
- @end
CaptureViewController.h部分關鍵代碼,主要是初始化截取界面,截取成功後的處理等:
[cpp] view plain copy
- - (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.主界面打開選項清單并選擇拍照或是從相冊選擇圖檔代碼:
[cpp] view plain copy
- //彈出選項清單選擇圖檔來源
- - (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;
- }
- }
拍照或選擇圖檔後的回調方法:
[cpp] view plain copy
- #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];
- }
- }
回調方法,顯示截取後的圖檔
[cpp] view plain copy
- #pragma mark - 圖檔回傳協定方法
- -(void)passImage:(UIImage *)image
- {
- //将截取的圖檔顯示在主界面
- imageView.image = image;
- }
最後就是一段縮放圖檔的方法:
[cpp] view plain copy
- #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