2012-09-04 17 views
9

का उपयोग करके विशिष्ट रिज़ॉल्यूशन के साथ फ़ोटो कैप्चर करना मैं लिखने के साथ कागज के ए 4 टुकड़ों की तस्वीरें लेना चाहता हूं। महत्वपूर्ण बात यह है कि, मैं पाठ को पठनीय बनाना चाहता हूं, लेकिन मुझे 2592x1936 पिक्सेल या 3264x2448 पिक्सेल जैसे संकल्प वाले चित्र नहीं चाहिए क्योंकि यह बहुत बड़ा होगा। साथ ही, मुझे लगता है कि कैप्चरिंग के बाद तस्वीर को रद्द करने में अतिरिक्त समय लगता है, इसलिए मैं भी इससे बचना चाहता हूं।UIImagePickerController

हम निम्नलिखित गुणों के बीच चयन कर सकते हैं:

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

अगर हम AVFoundation उपयोग कर रहे थे, हम प्रस्तावों this nice table से (शीर्षक के अंतर्गत "कैप्चर फिर भी चित्र") चुन सकते हैं।

लेकिन क्या UIImagePickerController के लिए एक समान तालिका है, उदाहरण के लिए कहता है कि UIImagePickerControllerQualityTypeHigh आईफोन 3gs पर 1920x1080 के बराबर है?

उत्तर

15

UIImagepickerController quality वीडियो रिकॉर्डिंग के लिए उपयोग किया जाता है (UIImagepickerController प्रॉपर्टी "वीडियो गुणवत्ता" में उपयोग किया जाता है)।

मुझे लगता है कि यदि आप यह निर्दिष्ट करना चाहते हैं कि सटीक फोटो रिज़ॉल्यूशन क्या होना चाहिए, तो आपको UIImagepickerController के बजाय एवी फाउंडेशन फ्रेमवर्क का उपयोग करना चाहिए। या जैसा आपने कहा, बाद में तस्वीर को रूपांतरित करें।

यह बाद में आकार बदलने के लिए (here पाया जाता है):

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

आशा इस मदद करता है!

+0

'alphaInfo' मुद्दा गलत इस्तेमाल किया प्रकार की वजह से शायद है। 'CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo (imageRef) का उपयोग करें; 'इसके बजाए। – Berik

4

एक शब्द में: नहीं।

कोई "समान तालिका" नहीं है क्योंकि आप की पसंद UIImagePickerController द्वारा गलत तरीके से समझ रहे हैं।

आप अभी भी UIImagePickerController के साथ छवियों पर कब्जा कर रहे हैं आप (अर्थात अधिकतम) आइपॉड टच या iPad 2) के साथ < 1 सांसद को iPhone 4s के साथ में उपकरण की गुणवत्ता सवाल-कहीं भी 8 सांसद से डिफ़ॉल्ट पर उन्हें मिल जाएगा।

AVFoundation के साथ, हालांकि, आपके पास विकल्प हैं, जिन सत्रों को आप संदर्भित करते हैं, उनके लिए धन्यवाद।

लेकिन इन AVFoundation सत्र प्रीसेट के विपरीत, UIImagePickerControllerUIImagePickerControllerQualityType विकल्प केवल गति वीडियो पर लागू होते हैं, अभी भी छवि कैप्चर नहीं करते हैं।

तो आपके पास कैप्चर आकार को नियंत्रित करने के लिए AVFoundation का उपयोग करने का विकल्प है, या उन्हें सहेजने से पहले पूर्ण आकार की छवियों को फिर से आकार देना; लेकिन UIImagePickerController जो भी आप चाहते हैं वह नहीं कर सकता, मुझे डर है।

2

Thermometer's answer के साथ समस्या यह है कि यह छवि अभिविन्यास के साथ खराब हो जाती है।

मैं this solution कि उन्मुखीकरण समस्या का हल और एक तेजी से प्रदर्शन किया है मिल गया है:

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

अपने स्विफ्ट के लिए 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 
} 
1

marcelosalloum's answer की एक तेजी से 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 
    } 
संबंधित मुद्दे