iOS UIImagePickerController Bug

  • Post author:
  • Post category:其他


这是在测试项目的时候,发现上传用户头像有一个问题,然后引发的探索:

代码:

/**
 修改头像
 */
- (void)modifyHeadshot {
    /*头像*/
    NSString *mediaType = AVMediaTypeVideo;
    AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
    if (authorizationStatus == AVAuthorizationStatusRestricted || authorizationStatus == AVAuthorizationStatusDenied) {
        /*询问是否允许使用照相机*/
        UIAlertController * alertC = [UIAlertController alertControllerWithTitle:@"摄像头访问受限" message:@"请去设置中修改权限" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
            [self dismissViewControllerAnimated:YES completion:nil];
        }];
        [alertC addAction:action];
        [self presentViewController:alertC animated:YES completion:nil];
    }else{
        UIAlertController *alertController = [[UIAlertController alloc] init];
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"从手机相册选择" style:0 handler:^(UIAlertAction * _Nonnull action) {
            LOG(@"从手机相册选择");

            // 创建图片选择控制器对象
            self.imagePickerController = [[UIImagePickerController alloc] init];
            self.imagePickerController.navigationBar.tintColor = [UIColor blackColor];
            // 设置允许编辑(照片)
            self.imagePickerController.allowsEditing = YES;
            // 设置相册的呈现样式
//            self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            // 设置代理
            self.imagePickerController.delegate = self;
            // 呈现
            [self presentViewController:self.imagePickerController animated:YES completion:nil];
        }];

        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"拍照" style:0 handler:^(UIAlertAction * _Nonnull action) {
            LOG(@"拍照");
            // 创建图片选择控制器对象
            self.imagePickerController = [UIImagePickerController new];
            self.imagePickerController.navigationBar.tintColor = [UIColor blackColor];
            // 设置允许编辑
            self.imagePickerController.allowsEditing = YES;
            // 设置相册的呈现样式 ---> 从��中
            self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
            // 设置代理
            self.imagePickerController.delegate = self;
            // 呈现
            [self presentViewController:self.imagePickerController animated:YES completion:nil];
        }];

        UIAlertAction *action3 = [UIAlertAction actionWithTitle:@"取消" style:1 handler:^(UIAlertAction * _Nonnull action) {
            LOG(@"取消");
        }];
        [alertController addAction:action2];
        [alertController addAction:action1];
        [alertController addAction:action3];
        [self presentViewController:alertController animated:YES completion:nil];
    }
}


/**
 图片返回代理方法
 */
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    // 将图片变成data,data进行base64编码成字符串
    UIImage *resultImage = info[UIImagePickerControllerEditedImage];
    id cropRect = [info valueForKey:@"UIImagePickerControllerCropRect"];

    NSData *imageData = UIImageJPEGRepresentation(resultImage, 0.1);

    NSString *base64Str = [imageData base64EncodedStringWithOptions:0];

    //调接口传给后台
}

先来看看Bug长什么样:

上传的是一张纯黄色的图片,然后

info[UIImagePickerControllerEditedImage]

取得的图片是这样色儿的


可以看到,获得的图片右侧,有一条黑色的长条,查询了一下,发现这里是苹果SDK的一个Bug,


因为

SDK中剪切的长方形范围计算错误了

,所以,得出的值肯定也就不对了

而且,这个问题,好像并没有引起苹果的注意。。。

所以,既然苹果SDK内的剪切范围计算有问题,那我们就自己来吧!


这里是解决方案


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    // 将图片变成data,data进行base64编码成字符串
    //获取原始图片自己处理
    UIImage *resultImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    CGRect crop = [[info valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue];
    resultImage = [self ordinaryCrop:resultImage toRect:crop];

    NSData *imageData = UIImageJPEGRepresentation(resultImage, 0.1);

    NSString *base64Str = [imageData base64EncodedStringWithOptions:0];

    //上传图片到后台
}

/**
 *  在指定范围内切割图片
 */
- (UIImage *)ordinaryCrop:(UIImage *)imageToCrop toRect:(CGRect)cropRect
{
    CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], cropRect);
    UIImage *cropped = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return cropped;
}

这样一来,就没有了以前的问题了

看下重新切后的图片


参考资料



版权声明:本文为wwwwwwwwwwwwdi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。