一行代碼實現(xiàn)調(diào)用系統(tǒng)相機和相冊獲取圖片

5.gif
- 使用擴展,對于簡單的調(diào)用系統(tǒng)原生相機和相冊封裝了一下。只需要一行代碼即可實現(xiàn)。
- 可以自定義圖片尺寸,傳入imageSize即可,回調(diào)包括UIImage和ImageData
1.代碼.h
#import <UIKit/UIKit.h>
typedef void(^ImagePickerCompletionHandler)(NSData *imageData, UIImage *image);
@interface UIViewController (ImagePicker)
- (void)pickImageWithCompletionHandler:(ImagePickerCompletionHandler)completionHandler;
- (void)pickImageWithpickImageCutImageWithImageSize:(CGSize)imageSize CompletionHandler:(ImagePickerCompletionHandler)completionHandler;
@end
2.代碼.m
//
// UIViewController+ImagePicker.m
//
//
// Created by tt on 8/3/18.
// Copyright ? 2018 . All rights reserved.
//
#import "UIViewController+ImagePicker.h"
#import <objc/runtime.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/PHPhotoLibrary.h>
#import <AVFoundation/AVCaptureDevice.h>
static void *kImagePickerCompletionHandlerKey = @"kImagePickerCompletionHandlerKey";
static void *kCameraPickerKey = @"kCameraPickerKey";
static void *kPhotoLibraryPickerKey = @"kPhotoLibraryPickerKey";
static void *kImageSizeKey = @"kimageSizeKey";
static void *isCut = @"isCut"; //截取
@interface UIViewController ()<UIActionSheetDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (nonatomic, strong) UIImagePickerController *cameraPicker;
@property (nonatomic, strong) UIImagePickerController *photoLibraryPicker;
@property (nonatomic, copy) ImagePickerCompletionHandler completionHandler;
@property (nonatomic, assign) BOOL isCutImageBool;
@property (nonatomic, assign) CGSize imageSize;
@end
@implementation UIViewController (ImagePicker)
- (void)pickImageWithCompletionHandler:(ImagePickerCompletionHandler)completionHandler {
self.completionHandler = completionHandler;
[self presentChoseActionSheet];
}
- (void)pickImageWithpickImageCutImageWithImageSize:(CGSize)imageSize CompletionHandler:(ImagePickerCompletionHandler)completionHandler
{
self.completionHandler = completionHandler;
self.isCutImageBool = YES;
self.imageSize = imageSize;
[self presentChoseActionSheet];
}
- (void)setUpCameraPickControllerIsEdit:(BOOL)isEdit {
self.cameraPicker = [[UIImagePickerController alloc] init];
self.cameraPicker.allowsEditing = isEdit; //拍照選去是否可以截取,和代理中的獲取截取后的方法配合使用
self.cameraPicker.delegate = self;
self.cameraPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
- (void)setUpPhotoPickControllerIsEdit:(BOOL)isEdit {
self.photoLibraryPicker = [[UIImagePickerController alloc] init];
self.photoLibraryPicker.allowsEditing = isEdit; // 相冊選取是否截圖
self.photoLibraryPicker.delegate = self;
//去掉毛玻璃效果 否則在ios11 下 全局設置了UIScrollViewContentInsetAdjustmentNever 導致導航欄遮住了內(nèi)容視圖
self.photoLibraryPicker.navigationBar.translucent = NO;
self.photoLibraryPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
- (void)presentChoseActionSheet {
//先創(chuàng)建好 不然調(diào)用的時候 第一次創(chuàng)建很慢 有2秒的延遲
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
//判斷相機可用
[self setUpCameraPickControllerIsEdit:self.isCutImageBool];
}
[self setUpPhotoPickControllerIsEdit:self.isCutImageBool];
UIAlertController * actionController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction * takePhotoAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:self.cameraPicker animated:YES completion:nil];
});
}
else {
UIAlertController * noticeAlertController = [UIAlertController alertControllerWithTitle:@"未開啟相機權(quán)限,請到設置界面開啟" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"現(xiàn)在就去" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//跳轉(zhuǎn)到設置界面
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL success) {
}];
}];
[noticeAlertController addAction:cancelAction];
[noticeAlertController addAction:okAction];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:noticeAlertController animated:YES completion:nil];
});
}
}];
}];
UIAlertAction * choseFromAlbumAction = [UIAlertAction actionWithTitle:@"從相冊選取" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//判斷相冊權(quán)限
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusNotDetermined || status == PHAuthorizationStatusAuthorized) {
//未知的 第一次訪問
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:self.photoLibraryPicker animated:YES completion:nil];
});
}
else {
UIAlertController * noticeAlertController = [UIAlertController alertControllerWithTitle:@"未開啟相冊權(quán)限,請到設置界面開啟" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"現(xiàn)在就去" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//跳轉(zhuǎn)到設置界面
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL success) {
}];
}];
[noticeAlertController addAction:cancelAction];
[noticeAlertController addAction:okAction];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:noticeAlertController animated:YES completion:nil];
});
}
}];
}];
[actionController addAction:cancelAction];
[actionController addAction:takePhotoAction];
[actionController addAction:choseFromAlbumAction];
[self presentViewController:actionController animated:YES completion:^{
}];
}
#pragma mark <UIImagePickerControllerDelegate>
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:nil];
UIImage *editedimage = [[UIImage alloc] init];
if(self.isCutImageBool){
//獲取裁剪的圖
editedimage = info[@"UIImagePickerControllerEditedImage"]; //獲取裁剪的圖
CGSize imageSize = CGSizeMake(413, 626);
if (self.imageSize.height>0) {
imageSize = self.imageSize;
}
editedimage = [self reSizeImage:editedimage toSize:imageSize];
}
else{
editedimage = info[@"UIImagePickerControllerOriginalImage"];
}
NSData *imageData = UIImageJPEGRepresentation(editedimage, 0.0001);//首次進行壓縮
UIImage *image = [UIImage imageWithData:imageData];
//圖片限制大小不超過 1M CGFloat kb = data.lenth / 1000; 計算kb方法 os 按照千進制計算
while (imageData.length/1000 > 1024) {
NSLog(@"圖片超過1M 壓縮");
imageData = UIImageJPEGRepresentation(image, 0.5);
image = [UIImage imageWithData:imageData];
}
self.completionHandler(imageData, image);
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize
{
UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
[image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return reSizeImage;
}
#pragma mark - setters & getters
- (void)setCompletionHandler:(ImagePickerCompletionHandler)completionHandler {
objc_setAssociatedObject(self, kImagePickerCompletionHandlerKey, completionHandler, OBJC_ASSOCIATION_COPY);
}
- (ImagePickerCompletionHandler)completionHandler {
return objc_getAssociatedObject(self, kImagePickerCompletionHandlerKey);
}
- (void)setCameraPicker:(UIImagePickerController *)cameraPicker {
objc_setAssociatedObject(self, kCameraPickerKey, cameraPicker, OBJC_ASSOCIATION_RETAIN);
}
- (UIImagePickerController *)cameraPicker {
return objc_getAssociatedObject(self, kCameraPickerKey);;
}
- (void)setPhotoLibraryPicker:(UIImagePickerController *)photoLibraryPicker {
objc_setAssociatedObject(self, kPhotoLibraryPickerKey, photoLibraryPicker, OBJC_ASSOCIATION_RETAIN);
}
- (UIImagePickerController *)photoLibraryPicker {
return objc_getAssociatedObject(self, kPhotoLibraryPickerKey);
}
- (void)setIsCutImageBool:(BOOL)isCutImageBool {
return objc_setAssociatedObject(self, isCut, @(isCutImageBool), OBJC_ASSOCIATION_RETAIN);
}
- (BOOL)isCutImageBool {
return [objc_getAssociatedObject(self, isCut) boolValue];
}
- (void)setImageSize:(CGSize)imageSize {
return objc_setAssociatedObject(self, kImageSizeKey, [NSValue valueWithCGSize:imageSize], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGSize)imageSize {
NSValue * value = objc_getAssociatedObject(self, kImageSizeKey);
return value.CGSizeValue;
}
@end
- 然后就只需要一句代碼調(diào)用就行啦,在控制器里導入頭文件
#import "UIViewController+ImagePicker.h"
2 .一句代碼調(diào)用
不使用裁剪功能,獲取原圖
[self pickImageWithCompletionHandler:^(NSData *imageData, UIImage *image) {
//這里就拿到圖片了
}];
使用裁剪功能-自定義圖片大小 我設置為400*400
[self pickImageWithpickImageCutImageWithImageSize:CGSizeMake(400, 400) CompletionHandler:^(NSData *imageData, UIImage *image) {
//這里就拿到圖片了
}];
- 包括了相冊和相機權(quán)限判斷,提示用戶開啟訪問權(quán)限并跳轉(zhuǎn)到設置界面開啟。
- 需要iOS8以上,因為使用了UIAlertController。
- 在info.plist文件添加相機和相冊訪問權(quán)限key 和value 文字描述隨便你寫什么都行,個人喜歡怎么寫就怎么寫。??
1 .相機
<key>Privacy - Camera Usage Description</key>
<string>是否允許App訪問相機</string>
2.相冊
<key>Privacy - Photo Library Usage Description</key>
<string>是否允許App訪問相冊</string> - ??ps:因為系統(tǒng)的界面按鈕文字是英文的,比如相機界面的 取消 按鈕,和相冊界面的 取消 按鈕,想要變成中文的話。
在info.plist文件里找到
<key>Localization native development region</key>
值改為
<string>China</string>
然后那些按鈕的文字就變成中文了。