在iOS 7中旋转相机和照片拍摄问题

时间:2014-05-01 08:36:00

标签: ios objective-c

几年前我收到了一个应用程序,要求从新客户端更新,并提供了原始代码。

在进行更新后,他们希望让应用再次运行,我们发现有一个错误,如果用户旋转设备拍摄风景照片,屏幕上的视图不会旋转并将照片拍摄为90度,而不是真正的横向。

这本来是一个快速的工作,已经变得非常头痛。

我有什么想法可以对下面的代码做些什么来解决这个问题?

非常感谢!

//
//  CameraViewController.m
// 
//
//  Created by XXX on 8/9/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "CameraViewController.h"
#import <ImageIO/ImageIO.h>

@implementation CameraViewController
@synthesize stillImageOutput, delegate;
@synthesize session, captureVideoPreviewLayer;

- (void)dealloc {
    [stillImageOutput release];
    [captureVideoPreviewLayer release];
    [session release];

    [super dealloc];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    self.session = [[AVCaptureSession alloc] init];
    session.sessionPreset = AVCaptureSessionPresetMedium;

    self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    captureVideoPreviewLayer.frame = cameraView.bounds;
    [cameraView.layer addSublayer:captureVideoPreviewLayer];

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    NSError *error = nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    if (!input) {
        // Handle the error appropriately.
        NSLog(@"ERROR: trying to open camera: %@", error);
    }
    [session addInput:input];

    stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
    [stillImageOutput setOutputSettings:outputSettings];

    [session addOutput:stillImageOutput];

    [session startRunning];

    canDismiss = 0;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:)
                                                 name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void) didRotate:(NSNotification *)notification {
    [UIView beginAnimations:nil context:nil];

    if ( UIInterfaceOrientationIsLandscape([[UIDevice currentDevice] orientation]) ) {
        [topView setFrame:CGRectMake(0, 0, 320, 27)];
        [bottomView setFrame:CGRectMake(0, 433, 320, 27)];
    } else {
        [topView setFrame:CGRectMake(0, 0, 320, 110)];
        [bottomView setFrame:CGRectMake(0, 350, 320, 110)];
    }

    switch ([[UIDevice currentDevice] orientation]) {
        case UIInterfaceOrientationPortrait:
            btnDone.transform = CGAffineTransformIdentity;
            btnTakePicture.transform = CGAffineTransformIdentity;
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            btnDone.transform = CGAffineTransformMakeRotation(M_PI);
            btnTakePicture.transform = CGAffineTransformMakeRotation(M_PI);
            break;
        case UIInterfaceOrientationLandscapeLeft:
            btnDone.transform = CGAffineTransformMakeRotation(3*M_PI_2);
            btnTakePicture.transform = CGAffineTransformMakeRotation(3*M_PI_2);
            break;
        default:
            btnDone.transform = CGAffineTransformMakeRotation(M_PI_2);
            btnTakePicture.transform = CGAffineTransformMakeRotation(M_PI_2);
            break;
    }

    [UIView commitAnimations];
}

-(IBAction)takePhoto {
    AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in stillImageOutput.connections)
    {
        for (AVCaptureInputPort *port in [connection inputPorts])
        {
            if ([[port mediaType] isEqual:AVMediaTypeVideo] )
            {
                videoConnection = connection;
                break;
            }
        }
        if (videoConnection) { break; }
    }

    NSLog(@"about to request a capture from: %@", stillImageOutput);
    canDismiss++;
    [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
     {
         CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
         if (exifAttachments)
         {
             // Do something with the attachments.
             NSLog(@"attachements: %@", exifAttachments);
         }
         else
             NSLog(@"no attachments");

         int width = [[[NSUserDefaults standardUserDefaults] objectForKey:@"image_width"] intValue];
         int height = [[[NSUserDefaults standardUserDefaults] objectForKey:@"image_height"] intValue];

         NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
         UIImage * image = [[UIImage alloc] initWithData:imageData];
         NSLog(@"Image w:%f h:%f", image.size.width, image.size.height);
         UIImage * rotatedimage;
         if ( UIInterfaceOrientationIsLandscape([[UIDevice currentDevice] orientation]) ) {

             // Rotate the image
             CGSize newSize = CGSizeMake(image.size.height, image.size.width);
             CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
             CGContextRef ctx = CGBitmapContextCreate (NULL, newSize.width, newSize.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
             CGColorSpaceRelease(colorSpace);
             if ( [[UIDevice currentDevice] orientation] == UIInterfaceOrientationLandscapeLeft ) {
                 CGAffineTransform transform = CGAffineTransformMakeTranslation(0.0, newSize.height);
                 transform = CGAffineTransformScale(transform, 1.0, -1.0);

                 CGContextScaleCTM(ctx, -1.0, 1.0);
                 CGContextTranslateCTM(ctx, -newSize.width, 0);
                 CGContextConcatCTM(ctx, transform);
             }
             CGContextDrawImage(ctx, CGRectMake(0, 0, newSize.width, newSize.height), image.CGImage);
             CGImageRef sourceImageRef = CGBitmapContextCreateImage(ctx);
             rotatedimage = [UIImage imageWithCGImage:sourceImageRef];
             CGContextRelease(ctx);

             NSLog(@"Rotated Image w:%f h:%f", rotatedimage.size.width, rotatedimage.size.height);

             // Scale the image
             newSize = CGSizeMake(width, height);
             UIGraphicsBeginImageContext(newSize);
             [rotatedimage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
             //image is the original UIImage
             UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
             UIGraphicsEndImageContext();
             NSLog(@"New Image w:%f h:%f", newImage.size.width, newImage.size.height);
             [delegate tookPhoto:newImage];
         } else {
             // Scale the image
             CGSize newSize = CGSizeMake(width, image.size.height/(image.size.width/width));
             UIGraphicsBeginImageContext( newSize );
             [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
             UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
             UIGraphicsEndImageContext();
             NSLog(@"New Image w:%f h:%f", newImage.size.width, newImage.size.height);

             // Chop out the middle
             CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
             CGContextRef ctx = CGBitmapContextCreate (NULL, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
             CGColorSpaceRelease(colorSpace);
             if ( [[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown ) {
                 CGAffineTransform transform = CGAffineTransformMakeTranslation(0.0, newImage.size.height);
                 transform = CGAffineTransformScale(transform, 1.0, -1.0);

                 CGContextScaleCTM(ctx, -1.0, 1.0);
                 CGContextTranslateCTM(ctx, -newImage.size.width, 0);
                 CGContextConcatCTM(ctx, transform);
                 CGContextDrawImage(ctx, CGRectMake(0, (newImage.size.height-height)/2, newImage.size.width, newImage.size.height), newImage.CGImage);
             } else {
                 CGContextDrawImage(ctx, CGRectMake(0, -(newImage.size.height-height)/2, newImage.size.width, newImage.size.height), newImage.CGImage);
             }
             CGImageRef sourceImageRef = CGBitmapContextCreateImage(ctx);
             CGContextRelease(ctx);
             [delegate tookPhoto:[UIImage imageWithCGImage:sourceImageRef]];
         }
         [image release];

         canDismiss--;
     }];
}

-(IBAction)done {
    if ( canDismiss == 0 ) {
        self.delegate = nil;
        //[self dismissModalViewControllerAnimated:YES];
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

@end

1 个答案:

答案 0 :(得分:0)

如果我没有误会你必须放置这段代码: 试试这个:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
   // Return YES for supported orientations
   if([landscapeAllowedID contains: currentViewID])
       return (interfaceOrientation == UIInterfaceOrientationPortrait) | (interfaceOrientation == UIInterfaceOrientationLandscape);
}

修改

还要将它添加到UIViewController。

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape; // etc
}

如果不起作用,请将代码放在自定义UINavigationController中。您必须使用UINavigationController让它知道当前查看的视图。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    if([landscapeAllowedID contains: currentViewID])
        return (interfaceOrientation == UIInterfaceOrientationPortrait) | (interfaceOrientation == UIInterfaceOrientationLandscape);
}