13

我想拍一张A4纸上写字的照片。重要的是,我希望文本可读,但我不希望图像分辨率为 2592x1936 像素或 3264x2448 像素,因为那样会太大。另外,我认为在拍摄后重新缩放照片需要额外的时间,所以我也想避免这种情况。

我们可以选择以下品质:

UIImagePickerControllerQualityTypeHigh = 0   
UIImagePickerControllerQualityTypeMedium          = 1  default value   
UIImagePickerControllerQualityTypeLow            = 2   
UIImagePickerControllerQualityType640x480         = 3,   
UIImagePickerControllerQualityTypeIFrame1280x720  = 4,   
UIImagePickerControllerQualityTypeIFrame960x540   = 5 

如果我们使用,我们可以从这个漂亮的表格中AVFoundation选择分辨率(在标题“捕获静止图像”下)。

但是有没有类似的表格UIImagePickerController,例如UIImagePickerControllerQualityTypeHigh在 iPhone 3gs 上等于 1920x1080?

4

5 回答 5

19

UIImagepickerController 质量用于视频录制(在 UIImagepickerController 属性“videoQuality”中使用)。

我想如果你想指定确切的照片分辨率应该是什么,你应该使用 AV Foundation 框架而不是 UIImagepickerController。或者如你所说,之后转换图片。

之后调整它的大小(在此处找到):

//  ==============================================================
//  resizedImage
//  ==============================================================
// Return a scaled down copy of the image.  

UIImage* resizedImage(UIImage *inImage, CGRect thumbRect)
{
    CGImageRef          imageRef = [inImage CGImage];
    CGImageAlphaInfo    alphaInfo = CGImageGetAlphaInfo(imageRef);

    // There's a wierdness with kCGImageAlphaNone and CGBitmapContextCreate
    // see Supported Pixel Formats in the Quartz 2D Programming Guide
    // Creating a Bitmap Graphics Context section
    // only RGB 8 bit images with alpha of kCGImageAlphaNoneSkipFirst, kCGImageAlphaNoneSkipLast, kCGImageAlphaPremultipliedFirst,
    // and kCGImageAlphaPremultipliedLast, with a few other oddball image kinds are supported
    // The images on input here are likely to be png or jpeg files
    if (alphaInfo == kCGImageAlphaNone)
        alphaInfo = kCGImageAlphaNoneSkipLast;

    // Build a bitmap context that's the size of the thumbRect
    CGContextRef bitmap = CGBitmapContextCreate(
                NULL,
                thumbRect.size.width,       // width
                thumbRect.size.height,      // height
                CGImageGetBitsPerComponent(imageRef),   // really needs to always be 8
                4 * thumbRect.size.width,   // rowbytes
                CGImageGetColorSpace(imageRef),
                alphaInfo
        );

    // Draw into the context, this scales the image
    CGContextDrawImage(bitmap, thumbRect, imageRef);

    // Get an image from the context and a UIImage
    CGImageRef  ref = CGBitmapContextCreateImage(bitmap);
    UIImage*    result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);   // ok if NULL
    CGImageRelease(ref);

    return result;
}

希望这可以帮助!

于 2012-09-06T10:05:39.220 回答
5

一句话:没有。

没有“相似表”,因为您误解UIImagePickerControllerQualityTypeHighUIImagePickerController.

如果您正在捕捉静止图像,UIImagePickerController您将获得相关设备的默认(即最高)质量——从 iPhone 4s 的 8 MP 到 iPod touch 或 iPad 2 的 < 1 MP)。

但是,借助 AVFoundation,您可以选择,这要归功于您引用的会话预设。

但与这些 AVFoundation 会话预设不同,这些UIImagePickerController UIImagePickerControllerQualityType选项仅适用于动态视频,而不适用于静态图像捕获。

因此,您可以选择使用 AVFoundation 来控制捕获大小,或者在保存之前重新调整全尺寸图像的大小;但UIImagePickerController恐怕不能做你想做的事。

于 2012-09-09T15:50:05.423 回答
2

温度计的答案的问题在于它与图像方向有关。

我发现这个解决方案可以解决方向问题并具有更快的性能:

- (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;
}
于 2014-12-04T19:16:06.813 回答
2

对于您的 Swift 2.1 项目,这是@marcelosalloum 代码的翻译:

func scaleAndRotateImage(image: UIImage, kMaxResolution: CGFloat) -> UIImage {
    var imageCopy: UIImage = image
    if let imgRef: CGImageRef = image.CGImage {

        let width = CGFloat(CGImageGetWidth(imgRef))
        let height = CGFloat(CGImageGetHeight(imgRef))

        var transform = CGAffineTransformIdentity
        var bounds = CGRectMake(0, 0, width, height)

        if width > kMaxResolution || height > kMaxResolution {
            let 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
            }
        }

        let scaleRatio = bounds.size.width / width
        let imageSize = CGSizeMake(width, height)
        let boundHeight: CGFloat
        let orient: UIImageOrientation = image.imageOrientation
        switch orient {
        case .Up:
            transform = CGAffineTransformIdentity

        case .UpMirrored:
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0)
            transform = CGAffineTransformScale(transform, -1.0, 1.0)

        case .Down:
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))

        case .DownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);

        case .LeftMirrored: //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 * CGFloat(M_PI) / 2.0);

        case .Left: //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 * CGFloat(M_PI) / 2.0);

        case .RightMirrored: //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, CGFloat(M_PI) / 2.0);

        case .Right: //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, CGFloat(M_PI) / 2.0);
        }
        UIGraphicsBeginImageContext(bounds.size)

        if let context: CGContextRef = UIGraphicsGetCurrentContext() {
            if orient == .Right || orient == .Left {
                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)
            imageCopy = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
        }
    }
    return imageCopy
}
于 2015-12-08T16:56:51.467 回答
2

marcelosalloum 的答案的快速 3 翻译:

private func scale(image originalImage: UIImage, toLessThan maxResolution: CGFloat) -> UIImage? {
    guard let imageReference = originalImage.cgImage else { return nil }

    let rotate90 = CGFloat.pi/2.0 // Radians
    let rotate180 = CGFloat.pi // Radians
    let rotate270 = 3.0*CGFloat.pi/2.0 // Radians

    let originalWidth = CGFloat(imageReference.width)
    let originalHeight = CGFloat(imageReference.height)
    let originalOrientation = originalImage.imageOrientation

    var newWidth = originalWidth
    var newHeight = originalHeight

    if originalWidth > maxResolution || originalHeight > maxResolution {
        let aspectRatio: CGFloat = originalWidth / originalHeight
        newWidth = aspectRatio > 1 ? maxResolution : maxResolution * aspectRatio
        newHeight = aspectRatio > 1 ? maxResolution / aspectRatio : maxResolution
    }

    let scaleRatio: CGFloat = newWidth / originalWidth
    var scale: CGAffineTransform = .init(scaleX: scaleRatio, y: -scaleRatio)
    scale = scale.translatedBy(x: 0.0, y: -originalHeight)

    var rotateAndMirror: CGAffineTransform

    switch originalOrientation {
    case .up:
        rotateAndMirror = .identity

    case .upMirrored:
        rotateAndMirror = .init(translationX: originalWidth, y: 0.0)
        rotateAndMirror = rotateAndMirror.scaledBy(x: -1.0, y: 1.0)

    case .down:
        rotateAndMirror = .init(translationX: originalWidth, y: originalHeight)
        rotateAndMirror = rotateAndMirror.rotated(by: rotate180 )

    case .downMirrored:
        rotateAndMirror = .init(translationX: 0.0, y: originalHeight)
        rotateAndMirror = rotateAndMirror.scaledBy(x: 1.0, y: -1.0)

    case .left:
        (newWidth, newHeight) = (newHeight, newWidth)
        rotateAndMirror = .init(translationX: 0.0, y: originalWidth)
        rotateAndMirror = rotateAndMirror.rotated(by: rotate270)
        scale = .init(scaleX: -scaleRatio, y: scaleRatio)
        scale = scale.translatedBy(x: -originalHeight, y: 0.0)

    case .leftMirrored:
        (newWidth, newHeight) = (newHeight, newWidth)
        rotateAndMirror = .init(translationX: originalHeight, y: originalWidth)
        rotateAndMirror = rotateAndMirror.scaledBy(x: -1.0, y: 1.0)
        rotateAndMirror = rotateAndMirror.rotated(by: rotate270)

    case .right:
        (newWidth, newHeight) = (newHeight, newWidth)
        rotateAndMirror = .init(translationX: originalHeight, y: 0.0)
        rotateAndMirror = rotateAndMirror.rotated(by: rotate90)
        scale = .init(scaleX: -scaleRatio, y: scaleRatio)
        scale = scale.translatedBy(x: -originalHeight, y: 0.0)

    case .rightMirrored:
        (newWidth, newHeight) = (newHeight, newWidth)
        rotateAndMirror = .init(scaleX: -1.0, y: 1.0)
        rotateAndMirror = rotateAndMirror.rotated(by: CGFloat.pi/2.0)
    }

    UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
    guard let context = UIGraphicsGetCurrentContext() else { return nil }
    context.concatenate(scale)
    context.concatenate(rotateAndMirror)
    context.draw(imageReference, in: CGRect(x: 0, y: 0, width: originalWidth, height: originalHeight))
    let copy = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return copy
  }
于 2017-04-04T16:28:45.107 回答