使用UIImagePickerController以特定分辨率捕捉照片

我想用A4写一张照片。 重要的是,我希望文本是可读的,但我不想像2592×1936像素或3264×2448像素分辨率的图像,因为这将是太大了。 此外,我认为拍摄后重新调整照片需要额外的时间,所以我想避免这一点。

我们可以select以下品质:

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

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

但是有没有类似的UIImagePickerController表,例如说iPhone 3gs的UIImagePickerControllerQualityTypeHigh等于1920×1080?

UIImagepickerController质量用于video录制(用于UIImagepickerController属性“videoQuality”)。

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

之后调整它(在这里find):

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

希望这可以帮助!

总之:不。

没有“类似的表”,因为你误解了UIImagePickerControllerQualityTypeHigh使用UIImagePickerController类似的东西。

如果您使用UIImagePickerController捕捉静态图像,则可以使用iPhone 4s的8 MP到iPod touch或iPad 2的<1 MP的任意位置,以相关设备的默认质量(即最高质量)获取它们。

有了AVFoundation,但是,您可以select,感谢您提到的会话预设。

但不像这些AVFoundation会话预设, UIImagePickerController UIImagePickerControllerQualityType选项只适用于运动video,而不是静止图像捕获。

因此,您可以select使用AVFoundation来控制捕捉大小,或在保存全尺寸图像之前重新resize; 但是恐怕UIImagePickerController不能做你想做的。

温度计的答案的问题是,它与图像方向拧紧。

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

 - (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; } 

对于您的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 } 

快速翻译marcelosalloum的答案 :

 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 } var 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 }