这是在测试项目的时候,发现上传用户头像有一个问题,然后引发的探索:
代码:
/**
修改头像
*/
- (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;
}
这样一来,就没有了以前的问题了