使用图像选择控制器来拍一张照片或一段影片,包含三个部分的处理,代码、系统以及两者之间的交互:
重要:UIImagePickerController 类仅支持纵向模式。这个类只能直接使用,不支持之泪后。这个类的视图层是室友的,不能修改,只有一个例外。在iOS3.1或以后版本,可以指定cameraOverlayView 属性到一个自定义视图,并使用该视图来呈现附加信息或管理相机界面与代码之间的交互。例如,可以用自定义标准控件替换默认工具,使用UIImagePickerController选择图片和拍照示例代码项目中所示
学习如何使用AV Foundation框架完全自定义媒体捕捉,可参见在AV Foundation编程指南中的媒体捕捉和访问相机。
应用运行的设备必须有相机。
如果拍照片或影片对你的应用至关重要,可以通过配置应用程序的 Info.plist 属性列表文件来指定UIRequiredDeviceCapabilities的key 。可查看信息属性列表关键参考中的UIRequiredDeviceCapabilities 来指定各种相机特性。
如果应用程序偶尔需要捕获媒体,即,即使设备没有相机,应用仍然可用,那么当应用在没有相机的设备上运行,你的代码应该遵循替换路径。
设备的相机必须可使用,可以通过UIImagePickerController 类的isSourceTypeAvailable:方法测试。
必须实现一个委托对象来响应用户交互。(可参见相机界面委托的实现。)
满足这些先决条件,可以创建并通过指定以下选项配置一个图像选择控制器:
注意:总是调用类的类方法并遵守返回值。不要假设设备有相机。即使这个设备有相机,如果这个相机不可用,这个方法会返回NO。
然而,在设置这个属性之前,通过调用availableMediaTypesForSourceType: 类方法检查媒体类型是否可用。如果将媒体属性设为空数组,或者数组中没有可用的媒体类型用于当前资源,系统会抛出异常。
使用内置的编辑控件时,图像选择控制器将执行某些选项。对于静态图像,选择器会以最大像素尺寸裁剪为正方形。对于电影,选择器会执行最大电影长度和分辨率。如果希望让用户编辑全尺寸媒体或指定自定义裁剪,则必须提供自己的编辑界面。
通过方法签名和条件测试,清单1验证了先决条件得到满足,继而实例化、配置和异步全屏显示相机的用户界面。
清单1全屏展示了相机界面
对于只捕捉静态图像的选择器,用kUTTypeImage替换这里的kUTTypeMovie 标识符或者依靠媒体类型属性的默认值,即kUTTypeImage。
清单1中startCameraControllerFromViewController:usingDelegate: 示例方法旨在通过如下动作方法来调用:
注意:如果没有指定委托符合UINavigationControllerDelegate 协议,在编译过程中可能会看到一个警告。然而,因为该协议的方法是可选的,警告没有关联运行时。为了消除警告,委托支持的协议列表包含UINavigationControllerDelegate 协议。
startCameraControllerFromViewController:usingDelegate:示例方法的结果是系统显示标准的相机界面,包括控制媒体捕获或取消,如图1所示。
清单2展示了一个视图选择控制器委托方法的实现。实现包括保存用户捕捉的静态图像或电影的代码。
而不是如本例中立即保存新媒体项目到用户相册中,可以调用自定义代码来处理。
官方原文:
https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/CameraAndPhotoLib_TopicsForIOS/Articles/TakingPicturesAndMovies.html
- 实例化并实现相机界面,这个接口是UIImagePickerController 类的实例。
- 系统管理相机几口和用户的交互。在典型的使用中,用户要么拍照片或影片,或者取消操作。
- 系统调用图像选择控制器委托对象方法,进而处理用户交互。例如,保存一张新照片到相册中。这个委托也负责摒除相机界面
默认的图像选择控制器包括各种特性,如图1所示
重要:UIImagePickerController 类仅支持纵向模式。这个类只能直接使用,不支持之泪后。这个类的视图层是室友的,不能修改,只有一个例外。在iOS3.1或以后版本,可以指定cameraOverlayView 属性到一个自定义视图,并使用该视图来呈现附加信息或管理相机界面与代码之间的交互。例如,可以用自定义标准控件替换默认工具,使用UIImagePickerController选择图片和拍照示例代码项目中所示
学习如何使用AV Foundation框架完全自定义媒体捕捉,可参见在AV Foundation编程指南中的媒体捕捉和访问相机。
创建和配置相机界面
为了展现相机界面,必须确保三件事:应用运行的设备必须有相机。
如果拍照片或影片对你的应用至关重要,可以通过配置应用程序的 Info.plist 属性列表文件来指定UIRequiredDeviceCapabilities的key 。可查看信息属性列表关键参考中的UIRequiredDeviceCapabilities 来指定各种相机特性。
如果应用程序偶尔需要捕获媒体,即,即使设备没有相机,应用仍然可用,那么当应用在没有相机的设备上运行,你的代码应该遵循替换路径。
设备的相机必须可使用,可以通过UIImagePickerController 类的isSourceTypeAvailable:方法测试。
必须实现一个委托对象来响应用户交互。(可参见相机界面委托的实现。)
满足这些先决条件,可以创建并通过指定以下选项配置一个图像选择控制器:
- 源类型
注意:总是调用类的类方法并遵守返回值。不要假设设备有相机。即使这个设备有相机,如果这个相机不可用,这个方法会返回NO。
- 媒体类型
然而,在设置这个属性之前,通过调用availableMediaTypesForSourceType: 类方法检查媒体类型是否可用。如果将媒体属性设为空数组,或者数组中没有可用的媒体类型用于当前资源,系统会抛出异常。
- 编辑控件
使用内置的编辑控件时,图像选择控制器将执行某些选项。对于静态图像,选择器会以最大像素尺寸裁剪为正方形。对于电影,选择器会执行最大电影长度和分辨率。如果希望让用户编辑全尺寸媒体或指定自定义裁剪,则必须提供自己的编辑界面。
- 委托对象
通过方法签名和条件测试,清单1验证了先决条件得到满足,继而实例化、配置和异步全屏显示相机的用户界面。
清单1全屏展示了相机界面
- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
usingDelegate: (id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil))
return NO;
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose picture or
// movie capture, if both are available:
cameraUI.mediaTypes =
[UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
[controller presentModalViewController: cameraUI animated: YES];
return YES;
}
如果在设备上可以使用静态图像和电影,清单1中提供了一个选择器,让用户获取两者。呈现一个只能捕获影片的选择器,例如,确保影片捕获可用,然后如下设置媒体类型属性:
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
(为了确保影片捕获可用,调用availableMediaTypesForSourceType: 类方法。)
对于只捕捉静态图像的选择器,用kUTTypeImage替换这里的kUTTypeMovie 标识符或者依靠媒体类型属性的默认值,即kUTTypeImage。
清单1中startCameraControllerFromViewController:usingDelegate: 示例方法旨在通过如下动作方法来调用:
- (IBAction) showCameraUI {
[self startCameraControllerFromViewController: self
usingDelegate: self];
}
注意,由于清单1中指定的方法签名,委托对象必须符合UIImagePickerControllerDelegate 和UINavigationControllerDelegateprotocols。
注意:如果没有指定委托符合UINavigationControllerDelegate 协议,在编译过程中可能会看到一个警告。然而,因为该协议的方法是可选的,警告没有关联运行时。为了消除警告,委托支持的协议列表包含UINavigationControllerDelegate 协议。
startCameraControllerFromViewController:usingDelegate:示例方法的结果是系统显示标准的相机界面,包括控制媒体捕获或取消,如图1所示。
为相机界面实现委托
当用户在相机界面点击一个按钮拍摄新照片或影片或只是取消操作,系统会通知委托用户的选择。然而,系统不显示相机界面。委托通过调用dismissModalViewControllerAnimated: 方法释放界面。正因为这个原因,通常,使用视图控制器显示相机界面。清单2展示了一个视图选择控制器委托方法的实现。实现包括保存用户捕捉的静态图像或电影的代码。
清单2 相机界面的委托方法
@implementation CameraViewController (CameraDelegateMethods)
// For responding to the user tapping Cancel.
- (void) imagePickerControllerDidCancel: (UIImagePickerController *) picker {
[[picker parentViewController] dismissModalViewControllerAnimated: YES];
[picker release];
}
// For responding to the user accepting a newly-captured picture or movie
- (void) imagePickerController: (UIImagePickerController *) picker
didFinishPickingMediaWithInfo: (NSDictionary *) info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
UIImage *originalImage, *editedImage, *imageToSave;
// Handle a still image capture
if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0)
== kCFCompareEqualTo) {
editedImage = (UIImage *) [info objectForKey:
UIImagePickerControllerEditedImage];
originalImage = (UIImage *) [info objectForKey:
UIImagePickerControllerOriginalImage];
if (editedImage) {
imageToSave = editedImage;
} else {
imageToSave = originalImage;
}
// Save the new image (original or edited) to the Camera Roll
UIImageWriteToSavedPhotosAlbum (imageToSave, nil, nil , nil);
}
// Handle a movie capture
if (CFStringCompare ((CFStringRef) mediaType, kUTTypeMovie, 0)
== kCFCompareEqualTo) {
NSString *moviePath = [[info objectForKey:
UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum (
moviePath, nil, nil, nil);
}
}
[[picker parentViewController] dismissModalViewControllerAnimated: YES];
[picker release];
}
@end
如果用户可以编辑图像并且用户成功的捕获到新图片,则imagePickerController:didFinishPickingMediaWithInfo: 方法的info参数包含一个字典,且该字典包含可编辑图像。如清单2中,将这张图像作为选择的图像。如果想存储原始图像,可以从字典中获得,如代码清单中所示。
而不是如本例中立即保存新媒体项目到用户相册中,可以调用自定义代码来处理。
官方原文:
https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/CameraAndPhotoLib_TopicsForIOS/Articles/TakingPicturesAndMovies.html