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"で使用されます)。

正確な写真の解像度を指定する場合は、UIImagepickerControllerの代わりにAVFoundationフレームワークを使用する必要があると思います。またはあなたが言ったように、後で画像を変換します。

後でサイズを変更するには(ここにあります):

//  ==============================================================
//  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

一言で言えば:いいえ。

のようなものがどのようにUIImagePickerControllerQualityTypeHigh使用されているかを誤解しているため、「類似のテーブル」はありませんUIImagePickerController

静止画像をキャプチャする場合はUIImagePickerController、問題のデバイスのデフォルト(つまり最大)品質で画像を取得します。iPhone4sの8MPからiPodtouchまたはiPad2の1MP未満までです。

ただし、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-Projectの場合、これは@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 に答える