iOS摄像头和相册-UIImagePickerController-浅析(转)
UIImagePickerController 这个类可以为大家提供照相的功能,以及图片,视频浏览的功能。
// 判断设备是否有摄像头
- (BOOL) isCameraAvailable{
return [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
}
// 前面的摄像头是否可用
- (BOOL) isFrontCameraAvailable{
return [UIImagePickerControllerisCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront];
}
// 后面的摄像头是否可用
- (BOOL) isRearCameraAvailable{
return [UIImagePickerControllerisCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear];
}
// 判断是否支持某种多媒体类型:拍照,视频
- (BOOL) cameraSupportsMedia:(NSString *)paramMediaType sourceType:(UIImagePickerControllerSourceType)paramSourceType{
__block BOOL result = NO;
if ([paramMediaType length] == 0){
NSLog(@"Media type is empty.");
return NO;
}
NSArray *availableMediaTypes =[UIImagePickerControlleravailableMediaTypesForSourceType:paramSourceType];
[availableMediaTypes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL*stop) {
NSString *mediaType = (NSString *)obj;
if ([mediaTypeisEqualToString:paramMediaType]){
result = YES;
*stop= YES;
} }];
return result;
}
// 检查摄像头是否支持录像
- (BOOL) doesCameraSupportShootingVideos{
return [self cameraSupportsMedia:( NSString *)kUTTypeMoviesourceType:UIImagePickerControllerSourceTypeCamera];
}
// 检查摄像头是否支持拍照
- (BOOL) doesCameraSupportTakingPhotos{
return [self cameraSupportsMedia:( NSString *)kUTTypeImagesourceType:UIImagePickerControllerSourceTypeCamera];
}
// 相册是否可用
- (BOOL) isPhotoLibraryAvailable{
return [UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary];
}
// 是否可以在相册中选择视频
- (BOOL) canUserPickVideosFromPhotoLibrary{
return [self cameraSupportsMedia:( NSString *)kUTTypeMoviesourceType:UIImagePickerControllerSourceTypePhotoLibrary];
}
// 是否可以在相册中选择视频
- (BOOL) canUserPickPhotosFromPhotoLibrary{
return [self cameraSupportsMedia:( NSString *)kUTTypeImagesourceType:UIImagePickerControllerSourceTypePhotoLibrary];
}
- (void)ClickControlAction:(id)sender{
// 判断有摄像头,并且支持拍照功能
if ([self isCameraAvailable] && [self doesCameraSupportTakingPhotos]){
// 初始化图片选择控制器
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[controller setSourceType:UIImagePickerControllerSourceTypeCamera];// 设置类型
// 设置所支持的类型,设置只能拍照,或则只能录像,或者两者都可以
NSString *requiredMediaType = ( NSString *)kUTTypeImage;
NSString *requiredMediaType1 = ( NSString *)kUTTypeMovie;
NSArray *arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType, requiredMediaType1,nil];
[controller setMediaTypes:arrMediaTypes];
// 设置录制视频的质量
[controller setVideoQuality:UIImagePickerControllerQualityTypeHigh];
//设置最长摄像时间
[controller setVideoMaximumDuration:10.f];
[controller setAllowsEditing:YES];// 设置是否可以管理已经存在的图片或者视频
[controller setDelegate:self];// 设置代理
[self.navigationController presentModalViewController:controller animated:YES];
[controller release];
} else {
NSLog(@"Camera is not available.");
}
}
typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
UIImagePickerControllerSourceTypePhotoLibrary,
UIImagePickerControllerSourceTypeCamera,
UIImagePickerControllerSourceTypeSavedPhotosAlbum
};
NSString *requiredMediaType = ( NSString *)kUTTypeImage;
NSString *requiredMediaType1 = ( NSString *)kUTTypeMovie;
NSArray *arrMediaTypes=[NSArray arrayWithObjects:requiredMediaType, requiredMediaType1,nil];
[controller setMediaTypes:arrMediaTypes];
// 保存图片后到相册后,调用的相关方法,查看是否保存成功
- (void) imageWasSavedSuccessfully:(UIImage *)paramImage didFinishSavingWithError:(NSError *)paramError contextInfo:(void *)paramContextInfo{
if (paramError == nil){
NSLog(@"Image was saved successfully.");
} else {
NSLog(@"An error happened while saving the image.");
NSLog(@"Error = %@", paramError);
}
}
// 当得到照片或者视频后,调用该方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary*)info{
NSLog(@"Picker returned successfully.");
NSLog(@"%@", info);
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
// 判断获取类型:图片
if ([mediaType isEqualToString:( NSString *)kUTTypeImage]){
UIImage *theImage = nil;
// 判断,图片是否允许修改
if ([picker allowsEditing]){
//获取用户编辑之后的图像
theImage = [info objectForKey:UIImagePickerControllerEditedImage];
} else {
// 照片的元数据参数
theImage = [info objectForKey:UIImagePickerControllerOriginalImage];
}
// 保存图片到相册中
SEL selectorToCall = @selector(imageWasSavedSuccessfully:didFinishSavingWithError:contextInfo:);
UIImageWriteToSavedPhotosAlbum(theImage, self,selectorToCall, NULL);
}else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]){
// 判断获取类型:视频
//获取视频文件的url
NSURL* mediaURL = [info objectForKey:UIImagePickerControllerMediaURL];
//创建ALAssetsLibrary对象并将视频保存到媒体库
// Assets Library 框架包是提供了在应用程序中操作图片和视频的相关功能。相当于一个桥梁,链接了应用程序和多媒体文件。
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
// 将视频保存到相册中
[assetsLibrary writeVideoAtPathToSavedPhotosAlbum:mediaURL
completionBlock:^(NSURL *assetURL, NSError *error) {
if (!error) {
NSLog(@"captured video saved with no error.");
}else{
NSLog(@"error occured while saving the video:%@", error);
}
}];
[assetsLibrary release];
}
[picker dismissModalViewControllerAnimated:YES];
}
// 当用户取消时,调用该方法
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissModalViewControllerAnimated:YES];
}
#pragma mark - 相册操作
- (void)ClickShowPhotoAction:(id)sender{
if ([self isPhotoLibraryAvailable]){
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[controller setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];// 设置类型
NSMutableArray *mediaTypes = [[NSMutableArray alloc] init];
if ([self canUserPickPhotosFromPhotoLibrary]){
[mediaTypes addObject:( NSString *)kUTTypeImage];
}
if ([self canUserPickVideosFromPhotoLibrary]){
[mediaTypes addObject:( NSString *)kUTTypeMovie];
}
[controller setMediaTypes:mediaTypes];
[controller setDelegate:self];// 设置代理
[self.navigationController presentModalViewController:controller animated:YES];
[controller release];
[mediaTypes release];
} }
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info方法,中的info值,会根据我们操作的类型不同,而产生了不同的数据信息:
当操作的为图片时::{
UIImagePickerControllerCropRect = "NSRect: {{0, 405}, {2448, 2449}}";
UIImagePickerControllerEditedImage = "";
UIImagePickerControllerMediaMetadata = {
DPIHeight = 72;
DPIWidth = 72;
Orientation = 6;
"{Exif}" = {
ApertureValue = "2.526068811667588";
BrightnessValue = "-0.0709875088566263";
ColorSpace = 1;
DateTimeDigitized = "2013:04:05 16:43:00";
DateTimeOriginal = "2013:04:05 16:43:00";
ExposureMode = 0;
ExposureProgram = 2;
ExposureTime = "0.05882352941176471";
FNumber = "2.4";
Flash = 24;
FocalLenIn35mmFilm = 35;
FocalLength = "4.28";
ISOSpeedRatings = (
400
);
MeteringMode = 5;
PixelXDimension = 3264;
PixelYDimension = 2448;
SceneType = 1;
SensingMethod = 2;
Sharpness = 0;
ShutterSpeedValue = "4.099543917546131";
SubjectArea = (
1631,
1223,
881,
881
);
WhiteBalance = 0;
};
"{TIFF}" = {
DateTime = "2013:04:05 16:43:00";
Make = Apple;
Model = "iPhone 4S";
Software = "5.1.1";
XResolution = 72;
YResolution = 72;
};
};
UIImagePickerControllerMediaType = "public.image";
UIImagePickerControllerOriginalImage = "";
}
{
UIImagePickerControllerMediaType = "public.movie";
UIImagePickerControllerMediaURL = "file://localhost/private/var/mobile/Applications/22A14825-DD7E-48E1-A1D5-2D85B82095B5/tmp/capture-T0x1363a0.tmp.etXfD4/capturedvideo.MOV";
}
1.UIImagePickerController的静态方法:
imagepicker = [[UIImagePickerController alloc]init];
//UIImagePickerController静态方法判断设备是否支持照相机/图片库/相册功能
/*
typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
UIImagePickerControllerSourceTypePhotoLibrary,
UIImagePickerControllerSourceTypeCamera,
UIImagePickerControllerSourceTypeSavedPhotosAlbum
};
*/
BOOL isCameraSupport = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
NSLog(@"support camera:%d",isCameraSupport);
//UIImagePickerController静态方法判断设备是否支持前置摄像头/后置摄像头
/*
typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
UIImagePickerControllerCameraDeviceRear,
UIImagePickerControllerCameraDeviceFront
};
*/
BOOL isRearSupport = [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear];
NSLog(@"rear support:%d",isRearSupport);
//UIImagePickerController静态方法判断设备是否支持前置摄像头闪光灯/后置摄像头闪光灯
/*
typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
UIImagePickerControllerCameraDeviceRear,
UIImagePickerControllerCameraDeviceFront
};
*/
BOOL isFlushSupport = [UIImagePickerController isFlashAvailableForCameraDevice:UIImagePickerControllerCameraDeviceRear];
NSLog(@"rear flash support:%d",isFlushSupport);
//UIImagePickerController静态方法返回前置摄像头/后置摄像头支持的拍摄类型
/*
typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraDevice) {
UIImagePickerControllerCameraDeviceRear,
UIImagePickerControllerCameraDeviceFront
};
*/
//返回类型有照片和视频
/*
enum {
UIImagePickerControllerCameraCaptureModePhoto,
UIImagePickerControllerCameraCaptureModeVideo
};
typedef NSUInteger UIImagePickerControllerCameraCaptureMode;
*/
NSArray* captureModes = [UIImagePickerController availableCaptureModesForCameraDevice:UIImagePickerControllerCameraDeviceRear];
for (NSNumber* mode in captureModes) {
NSLog(@"capture modes:%d",[mode integerValue]);
}
//UIImagePickerController静态方法返回照相机/相册/照片库所支持的媒体类型
/*
typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
UIImagePickerControllerSourceTypePhotoLibrary,
UIImagePickerControllerSourceTypeCamera,
UIImagePickerControllerSourceTypeSavedPhotosAlbum
};
*/
//返回类型有kUTTypeMovie,kUTTypeImage,其他类型均在<MobileCoreServices/MobileCoreServices.h>下
NSArray* mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
for (NSString* type in mediaTypes) {
NSLog(@"media types:%@",type);
}
2.UIImagePickerController属性详解:
//指定使用照相机模式,可以指定使用相册/照片库
imagepicker.sourceType = UIImagePickerControllerSourceTypeCamera;
//设置当拍照完或在相册选完照片后,是否跳到编辑模式进行图片剪裁。只有当showsCameraControls属性为true时才有效果
imagepicker.allowsEditing = YES;
//设置拍照时的下方的工具栏是否显示,如果需要自定义拍摄界面,则可把该工具栏隐藏
imagepicker.showsCameraControls = YES;
//设置使用后置摄像头,可以使用前置摄像头
imagepicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
//设置闪光灯模式
/*
typedef NS_ENUM(NSInteger, UIImagePickerControllerCameraFlashMode) {
UIImagePickerControllerCameraFlashModeOff = -1,
UIImagePickerControllerCameraFlashModeAuto = 0,
UIImagePickerControllerCameraFlashModeOn = 1
};
*/
imagepicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
//设置相机支持的类型,拍照和录像
imagepicker.mediaTypes = @[(NSString*)kUTTypeImage,(NSString*)kUTTypeMovie];
//设置拍摄时屏幕的view的transform属性,可以实现旋转,缩放功能
// imagepicker.cameraViewTransform = CGAffineTransformMakeRotation(M_PI*45/180);
// imagepicker.cameraViewTransform = CGAffineTransformMakeScale(1.5, 1.5);
//所有含有cameraXXX的属性都必须要sourceType是UIImagePickerControllerSourceTypeCamera时设置才有效果,否则会有异常
//设置UIImagePickerController的代理
imagepicker.delegate = self;
-(void)showCamera{
//用模态方式呈现imagepicker
[self presentModalViewController:imagepicker animated:YES];
}
使用 imagepicker.cameraViewTransform = CGAffineTransformMakeRotation(M_PI*45/180);旋转45度的效果:
使用imagepicker.cameraViewTransform = CGAffineTransformMakeScale(1.5, 1.5);全屏的效果,同时imagepicker.showsCameraControls =NO;隐藏工具栏:
使用imagepicker.allowsEditing = YES;出现的图片编辑效果,只有当imagepicker.showsCameraControls = YES;才有效果:
使用 imagepicker.mediaTypes = @[(NSString*)kUTTypeImage,(NSString*)kUTTypeMovie];支持拍照和视频的前后对比效果:
3.UIImagePickerController回调详解:
//成功获得相片还是视频后的回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
//通过UIImagePickerControllerMediaType判断返回的是照片还是视频
NSString* type = [info objectForKey:UIImagePickerControllerMediaType];
//如果返回的type等于kUTTypeImage,代表返回的是照片,并且需要判断当前相机使用的sourcetype是拍照还是相册
if ([type isEqualToString:(NSString*)kUTTypeImage]&&picker.sourceType==UIImagePickerControllerSourceTypeCamera) {
//获取照片的原图
UIImage* original = [info objectForKey:UIImagePickerControllerOriginalImage];
//获取图片裁剪的图
UIImage* edit = [info objectForKey:UIImagePickerControllerEditedImage];
//获取图片裁剪后,剩下的图
UIImage* crop = [info objectForKey:UIImagePickerControllerCropRect];
//获取图片的url
NSURL* url = [info objectForKey:UIImagePickerControllerMediaURL];
//获取图片的metadata数据信息
NSDictionary* metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
//如果是拍照的照片,则需要手动保存到本地,系统不会自动保存拍照成功后的照片
UIImageWriteToSavedPhotosAlbum(edit, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}else{
}
//模态方式退出uiimagepickercontroller
[imagepicker dismissModalViewControllerAnimated:YES];
}
//取消照相机的回调
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
//模态方式退出uiimagepickercontroller
[imagepicker dismissModalViewControllerAnimated:YES];
}
//保存照片成功后的回调
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo{
NSLog(@"saved..");
}
4.自定义相机拍照画面:
//设置拍照时的下方的工具栏是否显示,如果需要自定义拍摄界面,则可把该工具栏隐藏
imagepicker.showsCameraControls = NO;
UIToolbar* tool = [[UIToolbar alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height-55, self.view.frame.size.width, 75)];
tool.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem* cancel = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelCamera)];
UIBarButtonItem* add = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(savePhoto)];
[tool setItems:[NSArray arrayWithObjects:cancel,add, nil]];
//把自定义的view设置到imagepickercontroller的overlay属性中
imagepicker.cameraOverlayView = tool;
-(void)cancelCamera{
[imagepicker dismissModalViewControllerAnimated:YES];
}
-(void)savePhoto{
//拍照,会自动回调- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info,对于自定义照相机界面,拍照后回调可以不退出实现连续拍照效果
[imagepicker takePicture];
}
5.UIImagePickerController是继承UINavigationController,所以可以push和pop一些viewcontroller进行导航效果。例如,自定义照相机画面的时候可以在拍摄完后push一个viewcontroller用于对照片进行编辑。