2010-02-10 27 views
8

Khi bạn chụp ảnh với UIImagePickerController trên iPhone, tôi và nhiều cư dân internet đã tìm thấy bạn cần chạy hình ảnh thông qua chức năng này để định hướng chúng đúng cách bạn đang ở đó).Tăng tốc hoặc loại bỏ chức năng chậm này trong ứng dụng máy ảnh iPhone

Có một sợi khổng lồ về nó ở đây: http://discussions.apple.com/message.jspa?messageID=7276709

Đáng tiếc, chức năng này có thể mất vài giây để chạy và nó thực sự là một phiền toái. Nếu bạn muốn sử dụng điều này và cho phép người dùng chụp ảnh nhanh, thậm chí bạn cần thêm NSLock hoặc bạn sẽ gặp phải một số sự cố.

Làm cách nào để tăng tốc hoặc loại bỏ mã này?

// orient photos and scale them to kMaxResolution 
+ (UIImage*)scaleAndRotateImage:(UIImage *)image { 

    // we upload photos at a maximum resolution of 2048 x 1536 
    int kMaxResolution = 2048; 

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

Tôi cũng đang sử dụng mã này. Chỉ cần tò mò, nhu cầu của NSLock sẽ được áp dụng ở đâu? Tôi không thấy bất kỳ sự cố nào khi sử dụng mã này. Làm thế nào để bạn có nghĩa là "cho phép người dùng chụp ảnh nhanh"? – Jasarien

+0

Đối với những gì tôi có ý nghĩa về NSLock, hãy xem vài bình luận cuối cùng trên diễn đàn mà tôi đã liên kết. Bằng cách cho phép người dùng chụp ảnh nhanh, tôi có nghĩa là làm nền cho việc lưu ảnh. Bạn có chặn khi lưu ảnh vào đĩa không? Ngoài ra, ứng dụng của tôi ghi dữ liệu EXIF ​​vào ảnh trong quá trình này, do đó, có thêm công việc đang được thực hiện để nhấn mạnh bộ nhớ. –

+0

Tôi sử dụng một cái gì đó tương tự và nó rất, rất chậm. Có lẽ có một cách tốt hơn, rằng tôi không biết ... Câu hỏi hay. – Jordan

Trả lời

11

Bạn có thực sự cần thực hiện thao tác này ngay lập tức không? Độ phân giải màn hình của iPhone là 320x480 (và gấp đôi cho võng mạc) - chỉnh tỷ lệ hình ảnh xuống ít nhất, sau đó áp dụng các biến đổi (ít nhất là để hiển thị, sau đó nếu người dùng muốn làm điều gì đó với hình ảnh, bạn chạy phiên bản tốn kém hơn trong nền). Hãy xem dòng đầu tiên đó:

// we upload photos at a maximum resolution of 2048 x 1536 
int kMaxResolution = 2048; 

Đối với hầu hết các ứng dụng, bạn đang xoay hình ảnh khổng lồ này, sau đó tiếp tục vứt bỏ phần lớn dữ liệu được tính khi bạn thu nhỏ. Vứt bỏ dữ liệu đầu tiên bằng cách chia tỷ lệ (afaik, hoạt động rẻ hơn nhiều), sau đó xoay.

+2

Đây sẽ là câu trả lời của tôi. Rất nhiều vấn đề tốc độ trong thực tế là vấn đề nhận thức người dùng. Ví dụ: mọi người nhạy cảm với tốc độ khi chụp ảnh nhưng họ có điều kiện chờ tải lên qua IP. Bạn có thể lưu trữ hình ảnh một cách nhanh chóng ở định dạng mặc định khi chúng được chụp và sau đó chỉ xử lý chúng khi chúng cần được di chuyển/tải lên. – TechZen

0

Tôi tự hỏi tại sao bạn nghĩ rằng bạn cần phải mở rộng và xoay hình ảnh đến từ UIImagePicker. Tôi đã viết một vài ứng dụng khác nhau sử dụng máy ảnh và tôi chưa bao giờ cần phải làm điều này. Nếu bạn giải thích chi tiết hơn những gì bạn đang cố gắng làm, có lẽ chúng tôi có thể cung cấp cho bạn các đề xuất cụ thể hơn.

+1

Bạn cần làm điều này khi bạn không lưu vào Camera Roll. Bạn có thể tải lên ảnh bạn chụp bằng UIImagePickerController lên Flickr hoặc Picasa mà không bị định hướng sai không? –

+0

Tôi chưa thử tải ảnh trực tiếp lên Flickr từ ứng dụng của mình, nhưng nếu Flickr không hiểu cờ định hướng thì làm cách nào để thực hiện điều đúng với tải lên của máy ảnh? Rất kỳ quặc. –

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