代码之家  ›  专栏  ›  技术社区  ›  Andrew Johnson

在iPhone相机应用程序中加速或消除这种缓慢的功能

  •  8
  • Andrew Johnson  · 技术社区  · 15 年前

    当你在iPhone上使用uiImagePickerController拍照时,我和许多互联网用户发现你需要通过此功能运行这些图片,以正确定位它们(并在拍照时缩放它们)。

    这里有一条巨大的线: http://discussions.apple.com/message.jspa?messageID=7276709

    不幸的是,运行这个函数可能需要几秒钟,这真的很麻烦。如果你想使用它并让用户快速拍照,你甚至需要添加一个nslock,否则你会遇到一些崩溃。

    如何加速或消除此代码?

    // 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;
    }
    
    2 回复  |  直到 11 年前
        1
  •  11
  •   Tudor    13 年前

    你真的需要马上做这个手术吗?iPhone的屏幕分辨率是320x480(是视网膜的两倍)-将图像缩小到至少这个,然后应用转换(至少用于显示,然后如果用户想对图像做些什么,则在后台运行成本更高的版本)。看看第一行:

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

    对于大多数应用程序,您旋转这个巨大的图像,然后在向下收缩时继续丢弃大部分计算数据。首先通过缩放(Afaik,一种更便宜的操作)丢弃数据,然后旋转。

        2
  •  0
  •   Mark Bessey    15 年前

    我想知道为什么您认为需要缩放和旋转来自uiImagePicker的图像。我已经写了几个不同的应用程序,使用相机,我从来没有必要这样做。如果你更详细地解释你想做什么,也许我们可以给你更具体的建议。