iphone:从相机拍摄的图像改变方向

时间:2012-07-02 09:54:06

标签: iphone objective-c ios5

我制作了一个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。有同样的问题,但找不到解决方案。

请帮帮我。

感谢。

4 个答案:

答案 0 :(得分:4)

因此,在图像时,请存储设备的方向并将其作为参数传递给下面的方法 这里只给出方法的任何名称并传递参数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
    }   

如果图像不是必需的方向,那么在上述所有imageRotatedByDegrees的参数中加上90(即如果它是0则为0 + 90)或者你需要的。

编辑1

UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:1)

我通过苹果论坛(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;
}

答案 3 :(得分:1)

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