2009-02-11 32 views
43

Trong ứng dụng iPhone chỉ dành cho cảnh quan của mình, tôi khởi chạy UIImagePickerController để chụp ảnh, nhưng hình ảnh trực tiếp được hiển thị từ máy ảnh theo hướng dọc, với không gian trống xung quanh. Hình ảnh được xoay.UIImagePickerController camera preview là chân dung trong ứng dụng ngang

Sau khi nhấn nút camera, bản xem trước rất lộn xộn, với hầu hết màn hình xem trước tắt và chế độ xem không được căn chỉnh chính xác.

Apple đã thừa nhận rằng đây là lỗi và đang làm việc trên đó.

Câu hỏi của tôi là, có ai có xung quanh công việc (hợp pháp hoặc bất hợp pháp) cho phép tôi làm việc này ngay bây giờ không. Tôi sẽ không phát hành vào App Store với bản sửa lỗi bất hợp pháp, nhưng tôi sẽ có một ứng dụng tốt hơn để thử nghiệm người dùng - hiện tại máy ảnh không thể sử dụng được nhiều trong cảnh quan.

Tôi sẽ đính kèm dự án và hình ảnh thử nghiệm đơn giản nếu có thể.

Chỉnh sửa - chỉ để làm rõ, hình ảnh tôi nhận được chính xác ngang. Tôi muốn máy ảnh & giao diện người dùng xem trước để nhìn đúng!


Camera http://i42.tinypic.com/2zqsbpy.jpg

alt text http://i43.tinypic.com/168zam0.jpg

+5

Nói như một trọng tài NFL, "Sửa chữa bất hợp pháp, hành vi phạm tội 10 yards. Thứ hai." – gonzobrains

+5

Điều lạ lùng, bởi vì tôi không biết NFL là gì. –

+0

Lạ lùng cách chúng ta Bắc Mỹ (lưu ý: Bắc Mỹ không chỉ bao gồm Hoa Kỳ) giả sử mọi người đều biết NFL là gì! @ JaneSales nó là viết tắt của Liên đoàn bóng đá quốc gia, mà thực sự là khác với bóng đá bạn biết. –

Trả lời

87

Câu trả lời là lố bịch hơn bạn nghĩ. Tôi đã có cùng một vấn đề và tìm thấy một giải pháp trong một diễn đàn ở đâu đó. Vượt qua ảnh chụp của bạn thành một phương pháp như thế này:

// Code from: http://discussions.apple.com/thread.jspa?messageID=7949889 
- (UIImage *)scaleAndRotateImage:(UIImage *)image { 
    int kMaxResolution = 640; // 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 = roundf(bounds.size.width/ratio); 
     } 
     else { 
      bounds.size.height = kMaxResolution; 
      bounds.size.width = roundf(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; 
} 

:(

+0

vô lý, nhưng nó hoạt động :) – byron

+0

siêu phương pháp, thực sự công việc của mình! – freelancer

+0

Cảm ơn bạn rất nhiều vì phương pháp này! Vấn đề xoay khiến tôi gần như điên! – applefreak

0

Bạn sẽ cần phải thiết lập giao diện tùy chỉnh (với thanh công cụ và tiêu đề) như cameraOverlayView, cũng có thể bạn sẽ cần phải thiết allowsEditingshowsCameraControls vì điều đó sẽ ẩn các điều khiển standart và xem trước Đó là những gì tôi đã tìm thấy khi cần thiết trong ứng dụng mà tôi đang thực hiện (tôi nghĩ là cần phải chọn chân dung, nhưng tôi cần nó để áp dụng một số thay đổi ui nếu người dùng xoay thiết bị của mình để tạo cảnh quan). Mã có thể được cung cấp nếu cần.

P.S. Vẫn còn một số lỗi trong mã của tôi, nhưng tôi đang làm việc trên nó :)

1

Tôi không nghĩ rằng bạn cần thêm công việc để xử lý imageRotation hoặc dữ liệu EXIF. Hình ảnh drawInRect sẽ tự động xử lý nó.

Vì vậy, bạn chỉ cần có kích thước này hoặc hình ảnh và vẽ lại hình ảnh mới, điều đó là đủ.

1

Tôi không muốn xoay hình ảnh sau khi chụp; Tôi muốn chương trình xem trước hiển thị chính xác ở chế độ ngang. Vì vậy, trong iOS 6, tôi cho phép chế độ chân dung ở cấp ứng dụng, nhưng thiết lập bộ điều khiển xem gốc của ứng dụng được của lớp MyNonrotatingNavigationController, được xác định như sau:

@implementation MyNonrotatingNavigationController 

-(NSUInteger) supportedInterfaceOrientations 
{ 
    return UIInterfaceOrientationMaskLandscape; 
} 

@end 

Vì vậy, tất cả những gì đã từng thể hiện bên trong bộ điều khiển nav này sẽ được định hướng phong cảnh (bạn có thể làm điều này với bất kỳ bộ điều khiển xem nào). Bây giờ, khi tôi cần hiển thị bộ chọn hình ảnh, tôi thay thế bộ điều khiển chế độ xem gốc của cửa sổ ứng dụng bằng trình điều khiển chung hỗ trợ chế độ dọc. Để ngăn chặn trình điều khiển chế độ xem gốc cũ và các chế độ xem của nó từ deallocating, tôi duy trì các con trỏ tới chúng cho đến khi tôi sẵn sàng đưa chúng trở lại trong cửa sổ ứng dụng.

#define APP_DELEGATE ((MyAppDelegate*)[[UIApplication sharedApplication] delegate]) 
static UIViewController *pickerContainer = nil; 
static UIViewController *oldRoot = nil; 
static UIView *holdView = nil; 

-(void) showPicker 
{ 
    ...create UIImagePickerController... 

    oldRoot = APP_DELEGATE.window.rootViewController; 
    holdView = [[UIView alloc] initWithFrame:APP_DELEGATE.window.bounds]; 
    [holdView addSubview:oldRoot.view]; 

    pickerContainer = [UIViewController new]; 
    pickerContainer.view = [[UIView alloc] initWithFrame:APP_DELEGATE.window.bounds]; 
    APP_DELEGATE.window.rootViewController = pickerContainer; 
    [pickerContainer presentViewController:picker animated:YES completion:NULL]; 
} 

-(void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info 
{ 
    [pickerContainer dismissViewControllerAnimated:YES completion:^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      APP_DELEGATE.window.rootViewController = oldRoot; 
      [APP_DELEGATE.window addSubview:oldRoot.view]; 
      pickerContainer = nil; 
      oldRoot = nil; 
      holdView = nil; 
     }); 
    }]; 
} 

Loại đau, nhưng có vẻ như có tác dụng cho cả ảnh và video. Các điều khiển của trình chọn hình ảnh hiển thị ở chế độ dọc, nhưng phần còn lại của ứng dụng chỉ là kiểu ngang.

+0

Giải pháp tuyệt vời, cũng hoạt động trên iOS7. –

1

Tôi giải quyết vấn đề này bằng cách làm cho UIImagePickerController xuất hiện ở chế độ toàn màn hình, cũng là những gì Apple đề xuất cho iPad.

Từ UIImagePickerController documentation:

Trên iPad, nếu bạn chỉ định một loại nguồn UIImagePickerControllerSourceTypeCamera, bạn có thể trình bày các modally chọn hình ảnh (toàn màn hình) hoặc bằng cách sử dụng một popover. Tuy nhiên, Apple khuyên bạn chỉ nên trình bày giao diện camera toàn màn hình.

Các vấn đề liên quan