imageOrientation 返回向上,但照片显示颠倒
Posted
技术标签:
【中文标题】imageOrientation 返回向上,但照片显示颠倒【英文标题】:imageOrientation returns Up, but photo shows up upsidedown 【发布时间】:2012-03-18 03:05:00 【问题描述】:我正在从 iPad 照片库中抓取一些照片。我在横向模式下拍了几张测试照片,左侧是 iPad 主页按钮,然后是右侧。
所以在我的应用中,出于某种原因,有些照片是上下颠倒的。我检查了他们的imageOrientation
属性,它们都是0(意味着它们是UIImageOrientationUp
)。所以这意味着我什至不知道我需要旋转哪些照片。
发生了什么,我如何判断哪些照片需要旋转?谢谢
【问题讨论】:
看到这个github.com/cosnovae/fixUIImageOrientation 你也可以参考类似的帖子AVFoundation Image orientation off by 90 degrees in the preview but fine in Camera roll 【参考方案1】:一个 UIImage 有一个属性 imageOrientation,它指示 UIImageView 和其他 UIImage 消费者旋转原始图像数据。这个标志很有可能被保存到上传的 jpeg 图像中的 exif 数据中,但是您用来查看它的程序不支持该标志。
要在上传时旋转 UIImage 以正确显示,您可以使用如下类别: 在.h文件中
UIImagefixOrientation.h
@interface UIImage (fixOrientation)
- (UIImage *)fixOrientation;
@end
UIImagefixOrientation.m
@implementation UIImage (fixOrientation)
- (UIImage *)fixOrientation
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (self.imageOrientation)
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
switch (self.imageOrientation)
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation)
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
@end
并在捕获图像保存或从图库中选择图像期间调用此函数。
【讨论】:
您好,感谢您的支持。但是,一个潜在的问题是颠倒的文件都返回 UIImageOrientationUp。它们都不返回 0 以外的任何值,这是有问题的。 你能把代码发给我吗?我会从我这边试试。我解决你的错误。【参考方案2】:没有进入你的图像代码,可能是由于 ios 上的翻转坐标系?
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html
~截图:
将视图配置为使用翻转坐标
实现翻转坐标所需的第一步是确定视图的默认方向。如果您更喜欢使用翻转坐标,有两种方法可以在绘制之前配置视图的坐标系:
覆盖视图的 isFlipped 方法并返回 YES。应用翻转 在渲染之前立即转换为您的内容。
因此,在您看来,您可以尝试添加 -(BOOL)isFlipped
并返回 YES
并测试是否有任何不同。
【讨论】:
【参考方案3】:我也面临同样的问题。使用这个函数来解决:
- (UIImage *)scaleAndRotateImage:(UIImage *) image
int kMaxResolution = 320;
CGImageRef imgRef = image.CGImage;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGAffineTransform transform = CGAffineTransformIdentity;
CGRect bounds = CGRectMake(0, 0, width, height);
if (width > kMaxResolution || height > kMaxResolution)
CGFloat ratio = width/height;
if (ratio > 1)
bounds.size.width = kMaxResolution;
bounds.size.height = bounds.size.width / ratio;
else
bounds.size.height = kMaxResolution;
bounds.size.width = bounds.size.height * ratio;
CGFloat scaleRatio = bounds.size.width / width;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
CGFloat boundHeight;
UIImageOrientation orient = image.imageOrientation;
switch(orient)
case UIImageOrientationUp: //EXIF = 1
transform = CGAffineTransformIdentity;
break;
case UIImageOrientationUpMirrored: //EXIF = 2
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
break;
case UIImageOrientationDown: //EXIF = 3
transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationDownMirrored: //EXIF = 4
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
break;
case UIImageOrientationLeftMirrored: //EXIF = 5
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationLeft: //EXIF = 6
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
break;
case UIImageOrientationRightMirrored: //EXIF = 7
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeScale(-1.0, 1.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
case UIImageOrientationRight: //EXIF = 8
boundHeight = bounds.size.height;
bounds.size.height = bounds.size.width;
bounds.size.width = boundHeight;
transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
transform = CGAffineTransformRotate(transform, M_PI / 2.0);
break;
default:
[NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
UIGraphicsBeginImageContext(bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft)
CGContextScaleCTM(context, -scaleRatio, scaleRatio);
CGContextTranslateCTM(context, -height, 0);
else
CGContextScaleCTM(context, scaleRatio, -scaleRatio);
CGContextTranslateCTM(context, 0, -height);
CGContextConcatCTM(context, transform);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageCopy;
【讨论】:
以上是关于imageOrientation 返回向上,但照片显示颠倒的主要内容,如果未能解决你的问题,请参考以下文章
UIActivityViewController 复制忽略 imageOrientation
UIImagePickerController 中的 UIImage 方向问题