2011-12-13 3 views
7

Sono nuovo per iOS e sto sbattendo la testa contro il muro per questo per la settimana scorsa guardando in giro online per esercitazioni come: Dealing with Exif Images, Resizing images e molti più domande casuali qui su StackOverflow. Da questi, ho pensato che >=iOS 4.0, tutte le immagini prese dalla fotocamera contengono informazioni di rotazione basate su EXIF.iOS: ritaglio di un'immagine fissa acquisita da una fotocamera UIImagePickerController con overlay

ciò che non funziona: Dopo aver provato diverse tecniche di ritaglio immagine, tutto quello che finisce con il ritaglio dell'immagine in alcuni angoli casuali e anche, l'immagine risultante sembra essere ingrandita :(Quando uso un'immagine png da Internet (che non contengono dati EXIF), il ritaglio funziona. Per angoli casuali, intendo: l'immagine finisce ritagliata in alto a destra/in alto a sinistra e ingrandita.

Quello che sto cercando di realizzare:
Sto cercando di ritagliare un'immagine 100 px dall'alto e 100 px dal basso. In sostanza, sto usando due strisce di sovrapposizione: 1 in alto e 1 in basso con lo CGRect(0.0, 0.0, SCREEN_WIDTH, 100.0) [una striscia alta 100.0 px nella parte superiore] e un'altra CGRect(0.0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100.0) [altra striscia alta 100 px nella parte inferiore]. Ho bisogno di ottenere l'immagine tra queste due strisce: presumo che l'altezza dell'immagine sia: SCREEN_HEIGHT - 200.0.

Visualizzazione UIImagePickerController per la macchina fotografica con sovrapposizione:

 

    //SCREEN_HEIGHT = 480 and SCREEN_WIDTH = 320 
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; 

    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) 
    { 
     NSLog(@"Camera not available"); 
     return; 
    } 

    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; 
    imagePicker.delegate = self; 
    imagePicker.allowsEditing = NO; 


    // Hide the controls 
    imagePicker.showsCameraControls = NO; 
    imagePicker.navigationBarHidden = YES; 

    // Make camera view full screen 
    imagePicker.wantsFullScreenLayout = YES; 
    //imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y); 


    //Overlay 
    //OverlayView is a plain UIView with the CGRects mentioned in the question. 
    OverlayView *overlay = [[OverlayView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)]; 
    [overlay initOverlay:self]; 
    imagePicker.cameraOverlayView = overlay; 
    [self presentModalViewController:imagePicker animated:YES]; 
 

Codice per ruotare l'immagine in base a EXIF ​​imageOrientation proprietà e il ritaglio è

 

- (UIImage *) cropImage: (UIImage *) originalImage 
{ 

    CGRect cropRect = CGRectMake(0, 100.0, SCREEN_WIDTH, SCREEN_HEIGHT - 100); 

    CGRect transformedRect = [self TransformCGRectForUIImageOrientation:cropRect :originalImage.imageOrientation :originalImage.size]; 

    CGImageRef resultImageRef = CGImageCreateWithImageInRect(originalImage.CGImage, transformedRect); 

    UIImage *newImage = [[[UIImage alloc] initWithCGImage:resultImageRef scale:1.0 orientation:originalImage.imageOrientation] autorelease]; 

    return newImage; 
} 

- (CGRect) TransformCGRectForUIImageOrientation: (CGRect) source: (UIImageOrientation) orientation: (CGSize) imageSize { 

    switch (orientation) { 
     case UIImageOrientationLeft: { // EXIF #8 
      CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(
                      imageSize.height, 0.0); 
      CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate, 
                    M_PI_2); 
      return CGRectApplyAffineTransform(source, txCompound); 
     } 
     case UIImageOrientationDown: { // EXIF #3 
      CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(
                      imageSize.width, imageSize.height); 
      CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate, 
                    M_PI); 
      return CGRectApplyAffineTransform(source, txCompound); 
     } 
     case UIImageOrientationRight: { // EXIF #6 
      CGAffineTransform txTranslate = CGAffineTransformMakeTranslation(
                      0.0, imageSize.width); 
      CGAffineTransform txCompound = CGAffineTransformRotate(txTranslate, 
                    M_PI + M_PI_2); 
      return CGRectApplyAffineTransform(source, txCompound); 
     } 
     case UIImageOrientationUp: // EXIF #1 - do nothing 
     default: // EXIF 2,4,5,7 - ignore 
      return source; 
    } 

 

Il metodo cropImage sembra funzionare per le immagini scaricate da internet (che non contengono informazioni di orientamento). Sono a corto di opzioni. Per favore qualcuno potrebbe aiutarmi?

Grazie per la lettura!

+0

Sagar - ha il metodo seguito non ha causato la vostra applicazione al collasso? – Dejell

+0

@Odelya a quale metodo si riferisce? –

+0

La risposta di Matt. Ho il problema esatto e non riesco per un mese a ritagliare correttamente l'immagine – Dejell

risposta

17

quando è possibile, è più facile ignorare le immagini di disegno con core grafico:

- (UIImage *)cropImage:(UIImage *)oldImage { 
    CGSize imageSize = oldImage.size 
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageSize.width, 
                 imageSize.height - 200), 
              NO, 
              0.); 
    [oldImage drawAtPoint:CGPointMake(0, -100) 
       blendMode:kCGBlendModeCopy 
        alpha:1.]; 
    UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return croppedImage; 
} 
+0

+1 Grazie, Matt. Cercando di capire il codice: la linea # 2 "seleziona" l'immagine con il 200 px in basso ritagliato e quindi posiziona le nuove immagini di 100 px in alto rispetto all'immagine originale, troncando quindi la parte superiore di 100 px e la parte inferiore di 100 px a destra? Ha funzionato per me! Grazie mille per i tuoi sforzi !! Anche se l'immagine ritagliata non è esattamente simile a quella vista con la sovrapposizione della fotocamera, probabilmente dovrò modificare i nos. un po. A proposito, questo codice non è thread-safe giusto? E suppongo che la lib di CG fornisca un modo thread-safe per farlo, quindi sarebbe bello usarlo in modo thread-safe. –

+1

È thread-safe su iOS 4.0 e versioni successive, [QA 1637] (http://developer.apple.com/library/ios/#qa/qa1637/_index.html). – Mats

+0

+1, accettato! Fantastico, funziona così - splendidamente! GRAZIE A TON! Molto apprezzato! –