iOS开发—— UIImagePickerController获取相册和拍照
一、简单的拍照显示,或是从相册中直接选取照片
#import "ViewController.h"
@interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>{
UIImageView *imageView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 80, self.view.bounds.size.width-40, 300)];
imageView.backgroundColor = [UIColor grayColor];
[self.view addSubview:imageView];
UIButton *button = [UIButton buttonWithType:(UIButtonTypeCustom)];
button.frame = CGRectMake(100, 400, 100, 50);
button.backgroundColor = [UIColor redColor];
[button setTitle:@"相机" forState:UIControlStateNormal];
[button addTarget:self action:@selector(camera) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
UIButton *mButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
mButton.frame = CGRectMake(100, 470, 100, 50);
mButton.backgroundColor = [UIColor redColor];
[mButton setTitle:@"相册" forState:UIControlStateNormal];
[mButton addTarget:self action:@selector(photo) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:mButton];
}
- (void)camera {
//判断是否由摄像头
BOOL isCamera = [UIImagePickerController isCameraDeviceAvailable:(UIImagePickerControllerCameraDeviceRear)];
//UIImagePickerControllerCameraDeviceRear后置摄像头
//前置摄像头UIImagePickerControllerCameraDeviceFront
if (!isCamera) {
NSLog(@"没有后置摄像头");
return;
}
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.delegate = self;
imagePicker.editing = YES;//相机照的照片是否允许编辑
[self presentViewController:imagePicker animated:YES completion:^{
}];
}
//调取相册
- (void)photo {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
//选取相册照片
imageView.image = image;
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
二、在一的基础上得到的照片要保存本地
1、保存
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:@"userImage"];
[self dismissViewControllerAnimated:YES completion:nil];
}
2、取出
NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:@"userImage"];
UIImage *userImage = [UIImage imageWithData:imageData];
三、在二中取出的图片是有问题的。
一幅图片除了包含我们能看见的像素信息,背后还包含了拍摄时间,光圈大小,曝光等信息。UIImage类将这些细节信息都隐藏了起来,只提供我们关心的图片尺寸,图片方向等。用相机拍摄出来的照片含有EXIF信息,UIImage的imageOrientation属性指的就是EXIF中的orientation信息。如果我们忽略orientation信息,而直接对照片进行像素处理或者drawInRect等操作,得到的结果是翻转或者旋转90之后的样子。这是因为我们执行像素处理或者drawInRect等操作之后,imageOrientaion信息被删除了,imageOrientaion被重设为0,造成照片内容和imageOrientaion不匹配。
目前市面上的大部分数码相机和手机都会内置一个方向感应器,拍出的照片中会写如方向信息,但是通常都只会有前四种方向。这几种Mirrored方向通常都是手机前置摄像头自拍的时候才会设置。
enum {
exifOrientationUp = 1, // UIImageOrientationUp
exifOrientationDown = 3, // UIImageOrientationDown
exifOrientationLeft = 6, // UIImageOrientationLeft
exifOrientationRight = 8, // UIImageOrientationRight
// these four exifOrientation does not support by all camera, but IOS support these orientation
exifOrientationUpMirrored = 2, // UIImageOrientationUpMirrored
exifOrientationDownMirrored = 4, // UIImageOrientationDownMirrored
exifOrientationLeftMirrored = 5, // UIImageOrientationLeftMirrored
exifOrientationRightMirrored = 7, // UIImageOrientationRightMirrored
};
typedef NSInteger ExifOrientation;
所以,在对照片进行保存之后,也需要将imageOrientaion这个代表方向的值保存起来,取出的时候再调整图片的方向。废话不多说了,上代码:
1、保存
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
[[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(image) forKey:@"userImage"];
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:image.imageOrientation] forKey:@"userImage_imageOrientation"];
[self dismissViewControllerAnimated:YES completion:nil];
}
2、取出
NSData* imageData = [[NSUserDefaults standardUserDefaults] objectForKey:@"userImage"];
UIImage *userImage = [UIImage imageWithData:imageData];
NSInteger imageOrientation = [[userDefault objectForKey:@"userImage_imageOrientation"] integerValue];
imageView.image = [self fixOrientationWithImage:userImage AndImageOrientation:imageOrientation];
//根据保存的方向值选择图片
- (UIImage *)fixOrientationWithImage:(UIImage *)aImage AndImageOrientation:(NSInteger)imageOrientation {
if (imageOrientation == UIImageOrientationUp)
return aImage;
CGAffineTransform transform = CGAffineTransformIdentity;
switch (imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
default:
break;
}
switch (imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
default:
break;
}
CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
CGImageGetBitsPerComponent(aImage.CGImage), 0,
CGImageGetColorSpace(aImage.CGImage),
CGImageGetBitmapInfo(aImage.CGImage));
CGContextConcatCTM(ctx, transform);
switch (imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
break;
}
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
iOS开发—— UIImagePickerController获取相册和拍照的更多相关文章
- 李洪强iOS开发-网络新闻获取数据思路回顾
李洪强iOS开发-网络新闻获取数据思路回顾 01 创建一个继承自AFHTTPSessionManager的工具类:LHQNetworkTool 用来发送网络请求获取数据 1.1 定义类方法返回单例对 ...
- iOS开发之获取沙盒路径
iOS开发之沙盒机制(SandBox)具体解说了沙盒的一些机制.在开发中,我们须要对沙盒进行操作.所以我们须要获取到沙盒路径. 沙盒里的目录包含Documents.Library.tmp.这三个目录的 ...
- iOS开发之获取系统相册ALAssetLibrary
注:当你选择看这篇博客时想必你的应用还支持iOS8一下系统,如果你的应用要求最低版本大于iOS8,建议使用PhotoKit框架,效率更高 ALAssetsLibrary包含,ALAssetsLibra ...
- iOS开发中获取WiFi相关信息
iOS 开发中难免会遇到很多与网络方面的判断,这里做个汇总,大多可能是与WiFi相关的. 1.Ping域名.Ping某IP 有 时候可能会遇到ping 某个域名或者ip通不通,再做下一步操作.这里的p ...
- android开发之——获取相册图片和路径
Android开发获取相册图片的方式网上有很多种,这里说一个Android4.4后的方法,因为版本越高,一些老的api就会被弃用,新的api和老的api不兼容,导致出现很多问题. 比如:managed ...
- iOS开发中获取视图在屏幕上显示的位置
在iOS开发中,我们会经常遇到一个问题,例如,点击一个按钮,弹出一个遮罩层,上面显示一个弹框,弹框显示的位置在按钮附近.如果这个按钮的位置相对于屏幕边缘的距离是固定的,那就容易了,可以直接写死位置.可 ...
- ios uiimagepickercontroller 选择相册或者拍照上传
首先需要实现UIImagePickerControllerDelegate 代理 实现其imagePickerController 方法 这里用于选择图片或的拍照回调 //调用相机拍照 或者 图库选 ...
- iOS开发——打开手机相册,获取图片
1.添加代理UIImagePickerControllerDelegate 2.设置点击跳转事件 - (IBAction)picButton:(UIButton *)sender { NSLog(@& ...
- Android开发之获取相册照片和获取拍照照片
在Android的开发过程中,我们可能会读取手机里面的照片或者通过相机拍摄获取照片,这是两种常用的获取图片的方式,在做项目过程中也会经常遇到,下面来介绍一下这两种获取方式.. 1.从本地相册获取照片: ...
随机推荐
- iOS 程序性能优化
前言 转载自:http://www.samirchen.com/ios-performance-optimization/ 程序性能优化不应该是一件放在功能完成之后的事,对性能的概念应该从我们一开始写 ...
- elasticsearch高级配置之(一)----分片分布规则设置
cluster.routing.allocation.allow_rebalance 设置根据集群中机器的状态来重新分配分片,可以设置为always, indices_primaries_active ...
- 学习笔记——单例模式Singleton
单例模式,很容易理解,就它一个. 比如网络请求服务类WebReq.它自己生成请求线程,并管理请求数据的返回,所以我们使用它进行网络请求时,不用每次都new一个,只需要使用一个实例就行了.WebReq实 ...
- ExtJS4 的dom
Ext使用了三个核心的工具类对我们掌握的DOM进行了完美的封装. ┣ Ext.Element(几乎对DOM的一切进行了封彻底装) ┣ Ext.DomHelper(一个强大的操控UI界面的工具类) ┣ ...
- 转:jmeter性能测试---登录百度进行搜索
在做web程序性能测试时,loadrunner和jmeter是两款常用的工具,两者比较起来,jmeter非常轻巧,且开源免费,上手快.这里简单介绍下jmeter的使用,以登录百度进行搜索为例. jme ...
- 转:Selenium Grid+JAVA +Windows 配置(Selenium 2.0)
Selenium-Grid 允许你在多台机器的多个浏览器上并行的进行测试,也就是说,你可以同时运行多个测试.本质上来说就是,Selenium-Grid 支持分布式的测试执行.它可以让你的测试在一个分布 ...
- material design 的android开源代码整理
material design 的android开源代码整理 1 android (material design 效果的代码库) 地址请点击:MaterialDesignLibrary 效果: 2 ...
- 不停止MySQL服务增加从库的两种方式【转载】
现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库.前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作. ...
- php通过token验证表单重复提交
PHP防止重复提交表单 2016-11-08 轻松学PHP 我们提交表单的时候,不能忽视的一个限制是防止用户重复提交表单,因为有可能用户连续点击了提交按钮或者是攻击者恶意提交数据,那么我们在提交数据后 ...
- android脚步--Relativelayout设置
引自http://blog.csdn.net/lamp_zy/article/details/8035161 http://my.oschina.net/honeyming/blog/130761 以 ...