Iphone 为什么此裁剪代码会导致旋转图像?
这个问题的标题应该相当清楚。下面的代码执行裁剪操作,然后在图像视图中显示新裁剪的照片。问题在于,图像一旦被裁剪,就会以与原始源图像不同的方向显示。为什么呢?我该怎么办呢Iphone 为什么此裁剪代码会导致旋转图像?,iphone,objective-c,ios,Iphone,Objective C,Ios,这个问题的标题应该相当清楚。下面的代码执行裁剪操作,然后在图像视图中显示新裁剪的照片。问题在于,图像一旦被裁剪,就会以与原始源图像不同的方向显示。为什么呢?我该怎么办呢 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { [self.popoverController dismissPopoverAnimated:tr
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self.popoverController dismissPopoverAnimated:true];
NSString *mediaType = [info
objectForKey:UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:YES];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
UIImage *image = [info
objectForKey:UIImagePickerControllerOriginalImage];
CGRect rect = CGRectMake(0, ((image.size.height - image.size.width) / 2), image.size.width, image.size.width);
CGImageRef subImageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
CGRect smallBounds = CGRectMake(rect.origin.x, rect.origin.y, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));
UIGraphicsBeginImageContext(smallBounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, smallBounds, subImageRef);
croppedImage = [UIImage imageWithCGImage:subImageRef];
UIGraphicsEndImageContext();
imageView.image = croppedImage;
*编辑
根据指出问题的根本原因是删除EXIF标记的评论,我尝试用以下代码更正方向。这仍然不能解决问题,但我认为这是朝着正确方向迈出的一步。也许它会帮助某人对这个问题提出一个新的答案
if (image.imageOrientation == UIImageOrientationLeft) {
NSLog(@"left");
CGContextRotateCTM (context, radians(90));
} else if (image.imageOrientation == UIImageOrientationRight) {
NSLog(@"right");
CGContextRotateCTM (context, radians(-90));
} else if (image.imageOrientation == UIImageOrientationUp) {
NSLog(@"up");
// NOTHING
} else if (image.imageOrientation == UIImageOrientationDown) {
NSLog(@"down");
CGContextRotateCTM (context, radians(-180.));
}
请参见我认为您最好的选择是从传入图像中获取方向,然后通过适当的旋转创建新图像 从传入的信息字典中获取元数据:
NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
NSNumber *orientation = [metadata objectForKey:@"Orientation"];
然后,当您创建UIImage
时:
croppedImage = [UIImage imageWithCGImage:subImageRef
scale:1.0
orientation:[orientation intValue]];
希望这至少是您的一个起点。您应该做的是在处理之前修复图像方向,我遇到了同样的问题,我正在使用swift,因此我必须更改此答案: 但是代码工作得很好。请记住,它返回一个图像,而它没有编辑图像,我只是因为那个简单的错误而努力使它正确。顺便说一下,您不应该使用UIImageOrientation,而应该使用UIImageOrientation.rawValue,至少在swift中是这样 我将把swift的代码留在这里,希望能有所帮助:
extension UIImage {
public func fixOrientation() -> UIImage?{
if self.imageOrientation.rawValue == UIImageOrientation.Up.rawValue {
return self
}
var transform : CGAffineTransform = CGAffineTransformIdentity
switch self.imageOrientation.rawValue {
case UIImageOrientation.Down.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
case UIImageOrientation.DownMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
case UIImageOrientation.Left.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
case UIImageOrientation.LeftMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
case UIImageOrientation.Right.rawValue:
print("working on right orientation")
transform = CGAffineTransformTranslate(transform, 0, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
case UIImageOrientation.RightMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, 0, self.size.height)
transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
case UIImageOrientation.Up.rawValue: break
case UIImageOrientation.UpMirrored.rawValue: break
default: break
}
switch self.imageOrientation.rawValue {
case UIImageOrientation.UpMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case UIImageOrientation.DownMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.width, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case UIImageOrientation.LeftMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case UIImageOrientation.RightMirrored.rawValue:
transform = CGAffineTransformTranslate(transform, self.size.height, 0)
transform = CGAffineTransformScale(transform, -1, 1)
case UIImageOrientation.Up.rawValue: break
case UIImageOrientation.Down.rawValue: break
case UIImageOrientation.Left.rawValue: break
case UIImageOrientation.Right.rawValue: break
default: break
}
let bitmapInfo = CGImageGetBitmapInfo(self.CGImage)
let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height), CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage),
bitmapInfo.rawValue)
CGContextConcatCTM(ctx, transform)
switch self.imageOrientation {
case UIImageOrientation.Left:
CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
case UIImageOrientation.LeftMirrored:
CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
case UIImageOrientation.Right:
CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
case UIImageOrientation.RightMirrored:
CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
default:
CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage)
}
let cgimg = CGBitmapContextCreateImage(ctx)
let image = UIImage(CGImage: cgimg!)
return image
}
}
我相信苹果使用EXIF标签来实现照片的旋转。您的新图像可能缺少该方向信息,因此显示不正确。该图像来自iPhone摄像头,因此应该有EXIF标记。在将其绘制到上下文中时,您没有考虑EXIF数据。图像将始终处于“原始”方向。UIImage根据exif旋转它。除了将其原始绘制到一个没有exif数据的新UIImage中以及“未旋转”之外。是否有任何方法通过上下文保留exif数据?