MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Objective-C中的Camera与Photo Library访问

2021-07-036.9k 阅读

一、Objective-C 中相机访问基础

1.1 相机访问权限

在 iOS 应用中访问相机,首先需要获取用户授权。在项目的 Info.plist 文件中,添加以下权限描述:

<key>NSCameraUsageDescription</key>
<string>Your use of the camera is required to use camera functionality.</string>

上述代码添加了相机使用描述,当应用尝试访问相机时,系统会弹出提示框,显示该描述,请求用户授权。

1.2 引入相关框架

要在 Objective-C 中访问相机,需引入 AVFoundation 框架。在 .m 文件头部导入:

#import <AVFoundation/AVFoundation.h>

AVFoundation 框架提供了丰富的多媒体处理功能,包括相机捕获。

二、相机捕获会话设置

2.1 创建捕获会话

捕获会话(AVCaptureSession)是相机捕获的核心,它协调输入(相机)和输出(如照片或视频数据)。

AVCaptureSession *session = [[AVCaptureSession alloc] init];
if ([session canSetSessionPreset:AVCaptureSessionPresetPhoto]) {
    session.sessionPreset = AVCaptureSessionPresetPhoto;
}

上述代码创建了一个捕获会话,并设置其预设为照片捕获,不同的预设可满足不同分辨率和质量需求。

2.2 配置相机输入

相机输入(AVCaptureDeviceInput)用于获取相机数据。

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (input) {
    if ([session canAddInput:input]) {
        [session addInput:input];
    }
} else {
    NSLog(@"Error creating device input: %@", error);
}

这里首先获取默认的视频设备(相机),然后尝试创建设备输入并添加到捕获会话中。

2.3 配置照片输出

照片输出(AVCapturePhotoOutput)用于获取拍摄的照片数据。

AVCapturePhotoOutput *photoOutput = [[AVCapturePhotoOutput alloc] init];
if ([session canAddOutput:photoOutput]) {
    [session addOutput:photoOutput];
}

创建照片输出对象并添加到捕获会话。

三、相机拍摄操作

3.1 启动和停止捕获会话

在准备好捕获会话后,可启动和停止它。

[session startRunning];
// 停止会话
[session stopRunning];

启动会话后,相机开始捕获数据,停止会话则停止捕获。

3.2 拍摄照片

拍摄照片需使用 AVCapturePhotoOutput 的方法。

AVCapturePhotoSettings *photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey: AVVideoCodecTypeJPEG}];
[photoOutput capturePhotoWithSettings:photoSettings delegate:self];

上述代码设置照片格式为 JPEG 并发起拍摄,delegate 用于处理拍摄结果。

3.3 处理拍摄结果

实现 AVCapturePhotoCaptureDelegate 协议方法来处理拍摄的照片。

- (void)photoOutput:(AVCapturePhotoOutput *)output didFinishProcessingPhoto:(AVCapturePhoto *)photo error:(NSError *)error {
    if (!error) {
        NSData *jpegData = photo.fileDataRepresentation;
        UIImage *image = [UIImage imageWithData:jpegData];
        // 处理图片,如显示在 UIImageView 中
    } else {
        NSLog(@"Error capturing photo: %@", error);
    }
}

此方法在照片拍摄完成后调用,可获取照片数据并转换为 UIImage 进行后续处理。

四、照片库访问基础

4.1 照片库访问权限

访问照片库同样需要获取用户授权。在 Info.plist 文件中添加:

<key>NSPhotoLibraryUsageDescription</key>
<string>Your photos are used to provide the application with access to your photo library.</string>

4.2 引入相关框架

访问照片库需引入 Photos 框架。

#import <Photos/Photos.h>

Photos 框架提供了与照片库交互的接口。

五、读取照片库内容

5.1 请求权限

在访问照片库前,需检查并请求权限。

PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) {
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        if (status == PHAuthorizationStatusAuthorized) {
            // 授权成功,可访问照片库
        } else {
            // 授权失败处理
        }
    }];
} else if (status == PHAuthorizationStatusAuthorized) {
    // 已授权,可直接访问
} else {
    // 未授权处理
}

上述代码检查权限状态,若未确定则请求授权,并根据授权结果进行相应处理。

5.2 获取照片资产

照片资产(PHAsset)代表照片库中的一张照片或一段视频。

PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
[assets enumerateObjectsUsingBlock:^(PHAsset * _Nonnull asset, NSUInteger idx, BOOL * _Nonnull stop) {
    // 处理每个照片资产
}];

这里获取所有图片类型的资产,并通过枚举块处理每个资产。

5.3 加载照片数据

从照片资产加载实际照片数据。

PHImageManager *imageManager = [PHImageManager defaultManager];
[imageManager requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
    if (result) {
        // 使用加载的 UIImage
    }
}];

PHImageManager 用于请求加载照片,targetSize 可指定加载图片的大小。

六、向照片库添加照片

6.1 创建保存请求

要将照片保存到照片库,需创建保存请求。

[PHPhotoLibrary.sharedPhotoLibrary performChanges:^{
    PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
    if (success) {
        // 保存成功处理
    } else {
        NSLog(@"Error saving image: %@", error);
    }
}];

上述代码使用 PHPhotoLibraryperformChanges:completionHandler: 方法执行保存操作,PHAssetCreationRequest 用于创建保存资产的请求。

6.2 处理保存结果

在完成处理块中处理保存结果,成功时可进一步操作,失败时记录错误。

七、高级相机与照片库功能

7.1 相机捕获设置优化

7.1.1 调整相机焦距

可通过 AVCaptureDevice 的属性调整相机焦距。

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
    NSError *error = nil;
    if ([device lockForConfiguration:&error]) {
        device.focusMode = AVCaptureFocusModeAutoFocus;
        [device unlockForConfiguration];
    } else {
        NSLog(@"Error locking device for configuration: %@", error);
    }
}

上述代码检查设备是否支持自动对焦模式,若支持则设置为自动对焦。

7.1.2 调整相机曝光

类似地,可调整相机曝光。

if ([device isExposureModeSupported:AVCaptureExposureModeAutoExpose]) {
    NSError *error = nil;
    if ([device lockForConfiguration:&error]) {
        device.exposureMode = AVCaptureExposureModeAutoExpose;
        [device unlockForConfiguration];
    } else {
        NSLog(@"Error locking device for configuration: %@", error);
    }
}

这里检查并设置曝光模式为自动曝光。

7.2 照片库筛选与管理

7.2.1 按日期筛选照片

可通过 NSPredicate 按日期筛选照片资产。

NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:0];
NSDate *endDate = [NSDate date];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"creationDate >= %@ AND creationDate <= %@", startDate, endDate];
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.predicate = predicate;
PHFetchResult<PHAsset *> *dateFilteredAssets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:options];

上述代码创建了一个按日期范围筛选照片资产的谓词,并应用到 PHFetchOptions 中获取筛选后的资产。

7.2.2 删除照片库中的照片

删除照片库中的照片需谨慎操作,同样使用 PHPhotoLibraryperformChanges:completionHandler: 方法。

[PHPhotoLibrary.sharedPhotoLibrary performChanges:^{
    [PHAssetChangeRequest deleteAssets:@[asset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
    if (success) {
        // 删除成功处理
    } else {
        NSLog(@"Error deleting asset: %@", error);
    }
}];

此代码从照片库中删除指定的照片资产,并处理删除结果。

通过上述内容,我们详细了解了在 Objective-C 中如何全面地访问相机和照片库,从基础的权限获取到复杂的功能实现,涵盖了各种常见和高级的操作场景,希望能帮助开发者在 iOS 应用开发中更好地实现与相机和照片库相关的功能。