【问题标题】:iphone : image captured from camera changes orientationiphone:从相机拍摄的图像改变方向
【发布时间】:2012-07-02 09:54:06
【问题描述】:

我制作了一个 iphone 应用程序来从相机捕获图像并将该图像设置在下一个视图中。但问题是图像被旋转了。即风景图像变成potraite,protraite图像变成风景。 我参考了很多代码,但无法解决。

我的代码是:

- (void)btnCapturePressed
{
 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
        {

            picker=[[UIImagePickerController alloc] init];
            picker.delegate=self;

            [picker setAllowsEditing:YES];

            picker.sourceType=UIImagePickerControllerSourceTypeCamera;
            //[self.navigationController pushViewController:(UIViewController *)ipc animated:YES];
            [self presentModalViewController:picker animated:YES];
            [picker release];
      }
}

-(void) imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo :(NSDictionary *)info
{
           UIImage *imageToScale=[info objectForKey:UIImagePickerControllerOriginalImage];

            imgView = [[UIImageView alloc] initWithImage:imageToScale];

            [picker presentModalViewController:cropper animated:YES];
}

我还提到了link。有同样的问题,但找不到解决方案。

请帮帮我。

谢谢。

【问题讨论】:

  • 你的图片会旋转到某个特定的角度吗?
  • 所以你必须让它们在显示之前再次旋转 -90 如果你想怎么做这会解决你的问题,请向我寻求帮助
  • 如果你需要它的代码,只要问它,我会给你答案
  • 答案对你有用吗
  • 你的问题怎么解决了?

标签: iphone objective-c ios5


【解决方案1】:

因此,在拍摄图像时,存储设备的方向并将其作为参数传递给下面的方法 这里只需给方法起任何名称并传递参数orientation

switch (orientation) {
            case UIDeviceOrientationPortrait:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(0.))];
                break;
            case UIDeviceOrientationPortraitUpsideDown:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(180.))];
                break;
            case UIDeviceOrientationLandscapeLeft:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(90.))];
                break;
            case UIDeviceOrientationLandscapeRight:
                [featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(-90.))];
                break;
            case UIDeviceOrientationFaceUp:
            case UIDeviceOrientationFaceDown:
            default:
                break; // leave the layer in its last known orientation
        }

我在这里使用的宏DegreesToRadians()如下

static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

这肯定行得通。

快乐编码:)

编辑

如果上面的代码不能正常工作,那就用这个

@interface UIImage (RotationMethods)
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
@end

@implementation UIImage (RotationMethods)

- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees 
{   
    // calculate the size of the rotated view's containing box for our drawing space
    UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
    CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
    rotatedViewBox.transform = t;
    CGSize rotatedSize = rotatedViewBox.frame.size;

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize);
    CGContextRef bitmap = UIGraphicsGetCurrentContext();

    // Move the origin to the middle of the image so we will rotate and scale around the center.
    CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);

    //   // Rotate the image context
    CGContextRotateCTM(bitmap, DegreesToRadians(degrees));

    // Now, draw the rotated/scaled image into the context
    CGContextScaleCTM(bitmap, 1.0, -1.0);
    CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;

}
@end

然后调用上面的函数如下

switch (orientation) {
        case UIDeviceOrientationPortrait:
            image = [image imageRotatedByDegrees:0];
            break;
        case UIDeviceOrientationPortraitUpsideDown:
            image = [image imageRotatedByDegrees:180];
            break;
        case UIDeviceOrientationLandscapeLeft:
            image = [image imageRotatedByDegrees:-90];
            break;
        case UIDeviceOrientationLandscapeRight:
            image = [image imageRotatedByDegrees:90];
            break;
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
        default:
            break; // leave the layer in its last known orientation
    }   

如果图像不是所需的方向,则将 90 添加到上述所有 imageRotatedByDegrees 的参数(即,如果它是 0,那么它将是 0+90)或根据您的需要。

编辑 1

UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];

【讨论】:

  • 在拍摄图像时只需将设备方向作为参数传递给方法
  • featureLayer 是要旋转的图像
  • 好的,我不知道为什么,但编辑后的答案会对您有所帮助。只需将已编辑答案的@implement@interface 部分放入您要调用图像旋转的.m 文件中的第一个代码部分,然后按照答案中提到的调用所需度数的开关,这将绝对有效,因为它在我的一个项目中经过测试和使用
  • 然后只需将 -90 放入 switch 语句中即可解决,因此 4 个值分别为 -90、90、-180、0。
  • 对于那把 -270 和 -90 分别代替 -180 和 0 我认为这将解决问题,因为你说它旋转了 +90
【解决方案2】:

我一直在努力解决这个问题,但找到了一个更简单的解决方案:

  AVCaptureConnection *vc = [self.snapper connectionWithMediaType:AVMediaTypeVideo];

  // THIS IS THE KEY LINE!!!!!!!!!!!!!!!!!!!!!
  [vc setVideoOrientation:[self interfaceToVideoOrientation]];

  [self.snapper captureStillImageAsynchronouslyFromConnection:vc
                                            completionHandler:
   ^(CMSampleBufferRef buf, NSError *err) {
     NSData* data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:buf];
     UIImage* im = [UIImage imageWithData:data];
     // Do something with the image.
  }];


- (AVCaptureVideoOrientation)interfaceToVideoOrientation
{
  switch ([UIApplication sharedApplication].statusBarOrientation)
  {
    case UIInterfaceOrientationPortrait:
      return AVCaptureVideoOrientationPortrait;
    case UIInterfaceOrientationPortraitUpsideDown:
      return AVCaptureVideoOrientationPortraitUpsideDown;
    case UIInterfaceOrientationLandscapeRight:
      return AVCaptureVideoOrientationLandscapeRight;
    case UIInterfaceOrientationLandscapeLeft:
      return AVCaptureVideoOrientationLandscapeLeft;
    default:
      return AVCaptureVideoOrientationPortrait;
  }
}

在捕获之前设置视频方向现在解决了我的图像以错误方向显示的问题。

【讨论】:

  • 在处理这个定位问题一小时又一小时之后,你终于帮助了我。惊人的!!非常感谢,我的应用现在可以运行了。
【解决方案3】:

我有同样的问题,这对我有帮助。希望它也能帮助你。我花了 2 分钟来解决这个问题。 http://xcodetipss.blogspot.com/2012/04/image-rotated-when-taken-from-camera.html

【讨论】:

    【解决方案4】:

    我参考了苹果论坛(https://discussions.apple.com/thread/1537011?start=0&tstart=0)的讨论并找到了以下解决方案;它对我来说非常有效;我只是复制粘贴它,它就像宝石一样工作;

    -(UIImage *) scaleAndRotateImage(UIImage *)image
    {
     int kMaxResolution = 320; // Or whatever
    
     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;
    }
    

    【讨论】:

    • 谢谢你,这对我帮助很大——尤其是你展示了如何从图像中提取方向信息的地方!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 2012-03-08
    • 2018-09-15
    • 1970-01-01
    相关资源
    最近更新 更多