Objective-c:如何在启用纵向锁定的情况下在捕获后修复图像方向

Posted

技术标签:

【中文标题】Objective-c:如何在启用纵向锁定的情况下在捕获后修复图像方向【英文标题】:Objective-c:how to fix the image orientation after capture with portrait orientation lock on 【发布时间】:2017-03-27 10:41:26 【问题描述】:

当我从相机横向(右侧向上)拍照时,图像仍然是纵向的。我想在方向上旋转图像,因为它是从带有纵向锁定的相机拍摄的。如何做到这一点?

【问题讨论】:

【参考方案1】:

在保存或显示图像之前尝试以下代码。

    - (UIImage*) rotateImage:(UIImage* )originalImage 

    UIImageOrientation orientation = originalImage.imageOrientation;

    UIGraphicsBeginImageContext(originalImage.size);

    [originalImage drawAtPoint:CGPointMake(0, 0)];
    CGContextRef context = UIGraphicsGetCurrentContext();

     if (orientation == UIImageOrientationRight) 
         CGContextRotateCTM (context, [self radians:90]);
      else if (orientation == UIImageOrientationLeft) 
         CGContextRotateCTM (context, [self radians:90]);
      else if (orientation == UIImageOrientationDown) 
         // NOTHING
      else if (orientation == UIImageOrientationUp) 
         CGContextRotateCTM (context, [self radians:0]);
     

      return UIGraphicsGetImageFromCurrentImageContext();

- (CGFloat) radians:(int)degree 
    return (degree/180)*(22/7);
  

【讨论】:

【参考方案2】:

您可以尝试以下功能并检查是否有帮助:

- (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;

参考:https://gist.github.com/Donohue/2aa0e2f31c1155d717fe

【讨论】:

我试过这个方法,但它只适用于纵向锁定关闭。 :(

以上是关于Objective-c:如何在启用纵向锁定的情况下在捕获后修复图像方向的主要内容,如果未能解决你的问题,请参考以下文章

如何在不锁定活动方向的情况下锁定片段方向?

Android Activity 生命周期和锁定/解锁设备

如何将视图从纵向模式更改为横向模式并锁定它?

Flutter:如何按需设置和锁定屏幕方向

锁定视图以最初在横向(仅横向)目标-C 中启动

在ios中锁定纵向和横向[重复]