iOS--拍照、从相册选图并对图片进行裁剪
2015-10-15 22:00
435 查看
今天主要实现一个小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部分代码如下:
<font color="#000"><font face="Arial">#import <Foundation/Foundation.h>
@protocol PassImageDelegate <NSObject>
-(void)passImage:(UIImage *)image;
@end</font></font>
复制代码
CaptureViewController.h部分关键代码,主要是初始化截取界面,截取成功后的处理等:
<font color="#000"><font face="Arial">- (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];
}
</font></font>
复制代码
3.主界面打开选项列表并选择拍照或是从相册选择图片代码:
<font color="#000"><font face="Arial">//弹出选项列表选择图片来源
- (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;
}
}
</font></font>
复制代码
拍照或选择图片后的回调方法:
<font color="#000"><font face="Arial">#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];
}
}
</font></font>
复制代码
回调方法,显示截取后的图片
<font color="#000"><font face="Arial">#pragma mark - 图片回传协议方法
-(void)passImage:(UIImage *)image
{
//将截取的图片显示在主界面
imageView.image = image;
}</font></font>
复制代码
最后就是一段缩放图片的方法:
<font color="#000"><font face="Arial">#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;
}
</font></font>
复制代码
完成后到真机上运行,效果如下:
SDK的升级,拍照及从相册选取图片的实现过程发生了一点小变化,比如UIImagePickerControllerDelegate的回调方法。现结合一个Demo简要介绍其实现过程。首先,裁剪图片的功能借助了Github上的项目AGSimpleImageEditorView。不多说,一步步的看Demo的实现过程吧:
1.下载Github上这个项目工程到本地并将其拖入到自己的工程中(前提是你已经建立了工程
),由于AGSimpleImageEditorView不支持ARC,所以还要做相应的配置,设置编译器标签-fno-objc-arc:
另外,由于使用到图形处理和图片处理,所以还要另外导入两个库,如下图
完成后,按command+B编译试试,如果没问题,说明工程集成成功了,下面就可以开始编码了,如果不成功,检查一下错误来源,上述步骤是否完整。
代码部分:以下均为关键代码,具体细节没有列举,注释写的非常详细,就不赘述了
2.新建PassImageDelegate协议作为在展示界面和截取界面间传值的代理(这个demo用到两种传值方式,不是很了解的可以参考一下《IOS学习笔记30—两个ViewController间传值(一)》),新建CaptureViewController作为截取图片功能的模块。PassImageDelegate部分代码如下:
<font color="#000"><font face="Arial">#import <Foundation/Foundation.h>
@protocol PassImageDelegate <NSObject>
-(void)passImage:(UIImage *)image;
@end</font></font>
复制代码
CaptureViewController.h部分关键代码,主要是初始化截取界面,截取成功后的处理等:
<font color="#000"><font face="Arial">- (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];
}
</font></font>
复制代码
3.主界面打开选项列表并选择拍照或是从相册选择图片代码:
<font color="#000"><font face="Arial">//弹出选项列表选择图片来源
- (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;
}
}
</font></font>
复制代码
拍照或选择图片后的回调方法:
<font color="#000"><font face="Arial">#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];
}
}
</font></font>
复制代码
回调方法,显示截取后的图片
<font color="#000"><font face="Arial">#pragma mark - 图片回传协议方法
-(void)passImage:(UIImage *)image
{
//将截取的图片显示在主界面
imageView.image = image;
}</font></font>
复制代码
最后就是一段缩放图片的方法:
<font color="#000"><font face="Arial">#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;
}
</font></font>
复制代码
完成后到真机上运行,效果如下:
相关文章推荐
- iOS开发 检测字符串是否是空字符串
- [转] iOS --- "自释放"在iOS开发中的应用
- iOS 代理,代理是实现反向传值步骤
- iOS ---上传头像 裁剪
- iOS---头像选取(照相或者图片库)、大小等比缩放、生成圆形头像
- iOS开发总结之代码规范(下)
- iOS开发总结之代码规范(上)
- iOS 警告收录及科学快速的消除方法
- iOS 播放视频
- iOS:核心动画的详解介绍:CAAnimation(抽象类)及其子类
- iOS 核心动画
- 我的IOS学习历程 - 第六天2
- 我的IOS学习历程 - 第六天1
- IOS 开发者账号 (team账号)
- 我的IOS学习历程-第五天
- IOS 通知传值
- IOS 8 基本定位实现
- flash发布ipa安装到ios8真机测试
- iOS中NSString,NSData和char的相互转换,JSON串转化为NSDictionary或NSArray
- IOS NSMutableAttributedString 富文本的设置