问题描述
我认为我通过运行一个基本SDK设置为iOS 6.1的应用程序(甚至可能更低的版本,也没有测试过),在最新的iOS 7中发现一个错误
我的照片库中有此图片: ...那样!
不要使用 UIImagePickerControllerEditedImage
,而改用原始图片。
使用第三方裁剪库,例如或
编辑 - 由粉丝添加的非常简单的解决方案
令人惊讶的是,它可以简单而优雅地自己修剪:
{
// iOS中有一个错误。当使用ALBUM,你必须自己裁剪:
fromAlbum = [info objectForKey:UIImagePickerControllerOriginalImage];
fromAlbum = [fromAlbum fixOrientation];
CGRect crop = [[info valueForKey:@UIImagePickerControllerCropRect] CGRectValue];
fromAlbum = [self ordinaryCrop:fromAlbum toRect:crop];
}
这里是整个例程ordinaryCrop:toRect:
- (UIImage *)normalCrop:(UIImage *)imageToCrop toRect:(CGRect)cropRect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage],cropRect);
UIImage * cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
现在正如Jesse指出的,正确旋转图像是至关重要的。这个绝对不可思议的代码由Anomie做的工作:
修复UIImage方向... UIImage + fixOrientation.h
这很简单,希望它能帮助别人。再次感谢这里的无价答案。
I think I found a bug in latest iOS 7 by running an app with Base SDK set to iOS 6.1 (possibly even lower versions too, haven't tested that out yet)
I have this image in my photo library: http://i.imgur.com/7KUIGLt.jpg
I present a UIImagePickerController via:
UIImagePickerController *vc = [[UIImagePickerController alloc] init];
vc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
vc.delegate = self;
vc.allowsEditing = YES;
[self presentViewController:vc animated:YES completion:nil];
I save the chosen image to my desktop (I am running this on simulator, but this works on device too)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage* outputImage = [info objectForKey:UIImagePickerControllerEditedImage];
if (outputImage == nil) {
outputImage = [info objectForKey:UIImagePickerControllerOriginalImage];
}
NSData *d = UIImagePNGRepresentation(outputImage);
[d writeToFile:@"/Users/Admin/Desktop/test.png" atomically:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
This is the resulting image:
Notice the big black bar to the right. What's causing this?
To reproduce this, you need:
- iOS 7
- App with Base SDK set to 6.1 (maybe even lower SDKs too, i haven't tried yet)
- iPhone 5/5c/5s
- Only happens to pictures that were taken with iPhone 5/5c/5s camera (you can use the original image I linked above for testing)
NOTE: Just to be clear, the black bar is part of the actual image. The image you see there is not a screenshot of a UIImageView, but the actual image saved to disk and uploaded here...
Your question is "What's causing this?" So I'll focus on that instead of giving a workaround.This is definitely a bug in iOS 7 dealing with edited images in lower base SDKs. We can also rule out that XCode 5 & Base SDK 6.1 causing this because I'm getting the same issue with XCode 4.6.3 & 6.1 SDK running on iOS 7 Simulator.
The source of the problem is that the CropRect values that are calculated by the SDK are wrong.If you'll print out the info
NSDictionary
from imagePickerController:didFinishPickingMediaWithInfo
you'll see that:
iOS 7 running any SDK lower than 7 we'll get:
While running iOS 6 or 5 with their SDK will give us:
You're probably saying, hmm, those y values are changing between SDKs too. Well, yea, if you'll slide your pic all the way down and select it you'll also get a black bar at the bottom of the picture.
Suggested Solutions:
Don't use
UIImagePickerControllerEditedImage
and take the original picture instead.Calculate and do the cropping your self.
Use a 3rd party cropping library such as PEPhotoCropEditor or SSPhotoCropperViewController
Edit - very simple solution added by fan of the answer!
Amazingly, it can be this simple and elegant to crop it yourself:
{
// There is a bug in iOS. When using ALBUM, you must crop it yourself:
fromAlbum = [info objectForKey:UIImagePickerControllerOriginalImage];
fromAlbum = [fromAlbum fixOrientation];
CGRect crop = [[info valueForKey:@"UIImagePickerControllerCropRect"] CGRectValue];
fromAlbum = [self ordinaryCrop:fromAlbum toRect:crop];
}
Here's the whole routine ordinaryCrop:toRect:
-(UIImage *)ordinaryCrop:(UIImage *)imageToCrop toRect:(CGRect)cropRect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], cropRect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
Now as Jesse points out, it is critical to rotate the image properly. This absolutely incredible piece of code by Anomie does the job:
iOS UIImagePickerController result image orientation after upload
Fixing UIImage orientation .. UIImage+fixOrientation.h
It's that simple, hope it helps someone. Thanks again for the priceless answers here.
这篇关于UIImagePickerController错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!