iOS:批量存储图片工具

需求背景

用户相册中会存在10+w的图片,使用airdrop(隔空投送)存在连接不稳定导致传送失败的情况,而且需要批量反复传输。所以开发一款可以在iPhone端批量存储图片的app。

预置条件

1.xcode
2.objective-C或者swift语言基础

实现关键

一、创建视图

1.实现viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
    [self setupView];
    [self getPhotoInfor];
}

2.添加控件:类型包含UIImageView、UIButton、UITextView、UILabel

- (void)setupView {
    //获取屏幕尺寸
    CGRect rc = UIScreen.mainScreen.bounds;
    
    //实现UIImageView
    //在屏幕(20,50)的位置,添加一个【长=屏幕宽度-40,高=150】的UITextView
    self.textViewInfo = [[UITextView alloc] initWithFrame:CGRectMake(20, 50, rc.size.width-40, 150)]; 
    self.textViewInfo.userInteractionEnabled = NO; //不响应touch、move等动作
    self.textViewInfo.backgroundColor = UIColor.grayColor; //控件背景色
    self.textViewInfo.textColor = UIColor.blackColor; //控件里文字颜色
    [self.view addSubview:self.textViewInfo]; //控件添加到视图中

	//实现UIButton
self.btnPick = [[UIButton alloc] initWithFrame:CGRectMake(70, 600, 100, 30)];
    self.btnPick.backgroundColor = UIColor.blueColor;
    [self.btnPick setTitle:@"选择图片" forState:UIControlStateNormal]; //设置控件名称
    //点击控件时,调用"actionOnPickDidClicked"方法
    //forControlEvents动作详见说明:https://www.cnblogs.com/whyandinside/archive/2013/10/26/3388908.html
    [self.btnPick addTarget:self action:@selector(actionOnPickDidClicked) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:self.btnPick];

}

3.实现效果图
在这里插入图片描述
搭好界面后,就需要具体实现点击操作方法,我们的需求是:

  • 点击【选择图片】,调用系统相册或者相机,进行选图/拍照
  • 选中的图像展示在imageView中
  • 输入需要重复保存的数量,点击【保存图片】,触发图像保存
  • 显示当前保存的进度,可以取消保存

二、权限管理

在【选择图片】时,需要有权限管理,在授予照片、相机权限后,才能打开系统相册或者系统相机,此时需要实现“UIImagePickerController”(图像选取器)类的一些方法

以相机权限为例:

- (void)setUpCameraPickControllerIsEdit:(BOOL)isEdit {
    self.cameraPicker = [[UIImagePickerController alloc] init];
    self.cameraPicker.allowsEditing = isEdit; //拍照选去是否可以截取,和代理中的获取截取后的方法配合使用
    self.cameraPicker.delegate = self; //设置代理
    self.cameraPicker.sourceType = UIImagePickerControllerSourceTypeCamera;//指定媒体类型是相机/相册/相簿
}
详见:https://blog.csdn.net/qq_36136586/article/details/79074143
- (void)presentChoseActionSheet {
    
    //先创建好 不然调用的时候 第一次创建很慢 有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:@"未开启相机权限,请到设置界面开启" message:nil preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                    
                }];
                
                UIAlertAction * okAction = [UIAlertAction actionWithTitle:@"现在就去" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                    //跳转到设置界面
                    [[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];
    
    [self presentViewController:actionController animated:YES completion:^{
        
    }];
}

实现效果
在这里插入图片描述

三、图像处理

1.选中的图像需要展示在界面上,以确保选中的图像正确

- (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);
}

2.选中的图片进行保存

- (void)saveImage {
    UIImageWriteToSavedPhotosAlbum(self.imageToSave, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}

四、异常处理

1.未选择图片、未输入需要保存的数量

- (void)actionOnSaveDidClicked {
    self.countToSave = [self.textField.text longLongValue];
    if (self.imageToSave == NULL || self.countToSave <= 0) {
        UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"请选择图片,并输入有效数量" message:@"" preferredStyle:UIAlertControllerStyleAlert];
        [self presentViewController:alert animated:YES completion:nil];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self dismissViewControllerAnimated:YES completion:nil];
        });
        return;
    }
    self.labelProgressToSave.textColor=UIColor.blackColor;
    self.countSaved = 0;
    [self enterSave];
}

- (void)enterSave {
    [self dismissViewControllerAnimated:NO completion:nil];
    if (self.isCancelSave || self.countSaved >= self.countToSave) {
        return;
    }
    
    NSString *info = [NSString stringWithFormat:@"保存进度 : 当前第%ld/%ld",self.countSaved+1, self.countToSave];
    self.labelProgressToSave.text=info;
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        [self saveImage];
    });
}

2.图像保存失败

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    if (error == NULL) {
        self.countSaved += 1;
        [self enterSave];
    } else {
        [self dismissViewControllerAnimated:NO completion:nil];
        UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"保存失败" message:@"重启一下吧" preferredStyle:UIAlertControllerStyleAlert];
        [self presentViewController:alert animated:YES completion:nil];
    }
}

3.取消保存

- (void)actionOnCancelDidClicked {
    self.countSaved = self.countToSave;  //设置当前保存的数量为需要的保存数,即可停止保存了
    [self enterSave];
}

最终实现效果

保存图像
在这里插入图片描述

取消保存
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值