2010-06-27 15 views
15

J'essaye de comprendre s'il y a n'importe quelle manière de refléter une image. Par exemple, prenez une photo du visage de quelqu'un, puis coupez-la en deux et montrez à quoi ressemble son visage, de chaque côté. Il ne semble pas y avoir de trucs comme ça dans les fonctions CGAffineTransform. Experts en graphiques s'il vous plaît aider!Comment est-ce que je miroir une image UIImage de UIImagePickerController

Répondre

34

Le "truc" de base consiste ici à utiliser une transformation d'échelle autour de l'axe X ou Y avec un facteur de -1. Par exemple, vous pouvez l'utiliser pour créer une « bascule autour de l'axe horizontal » transform:

CGAffineTransform transform = CGAffineTransformScale(transform, -1, 1); 

Ensuite, vous pouvez définir la propriété transform sur un UIImageView pour retourner l'image assignée, ou concaténer avec une autre transformation de faire des effets plus sophistiqués. Pour obtenir l'effet exact que vous avez décrit, vous devrez peut-être écrire un code de dessin personnalisé pour dessiner votre image originale dans un contexte, puis superposer la moitié retournée au-dessus. C'est relativement simple dans Core Graphics.

+4

ou utiliser CGAffineTransformMakeScale à savoir picker.cameraViewTransform = CGAffineTransformMakeScale (-1, 1) // – khunshan

+1

rapide Excellent! J'ai utilisé 'myImageView.transform = CGAffineTransformMakeScale (-1, 1);' –

19

Si vous ne prévoyez soutenir 4.0+

UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored; 
switch (image.imageOrientation) { 
    case UIImageOrientationUp: break; 
    case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break; 
    // ... 
} 
UIImage * flippedImage = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:flippedOrientation]; 
12

Vous pouvez penser, pourquoi embêter avec l'instruction switch outrageusement longue?

? UIImage *flip = [UIImage imageWithCGImage:image.CGImage 
?          scale:image.scale 
?        orientation:(image.imageOrientation + 4) % 8]; 

Et si vous jetez un oeil à l'ENUM vous pouvez voir que l'arithmétique modulaire ferait:

typedef NS_ENUM(NSInteger, UIImageOrientation) { 
    UIImageOrientationUp,   // default orientation 
    UIImageOrientationDown,   // 180 deg rotation 
    UIImageOrientationLeft,   // 90 deg CCW 
    UIImageOrientationRight,   // 90 deg CW 
    UIImageOrientationUpMirrored, // as above but image mirrored along other axis. horizontal flip 
    UIImageOrientationDownMirrored, // horizontal flip 
    UIImageOrientationLeftMirrored, // vertical flip 
    UIImageOrientationRightMirrored, // vertical flip 
}; 

Mais ce code est trop intelligent. Vous devriez écrire une fonction avec une instruction switch explicite à la place. Par exemple.

UIImageOrientation mirroredImageOrientation(UIImageOrientation orientation) { 
    switch(orientation) { 
     case UIImageOrientationUp: return UIImageOrientationUpMirrored; 
     case UIImageOrientationDown: return UIImageOrientationDownMirrored; 
     case UIImageOrientationLeft: return UIImageOrientationLeftMirrored; 
     case UIImageOrientationRight: return UIImageOrientationRightMirrored; 
     case UIImageOrientationUpMirrored: return UIImageOrientationUp; 
     case UIImageOrientationDownMirrored: return UIImageOrientationDown; 
     case UIImageOrientationLeftMirrored: return UIImageOrientationLeft; 
     case UIImageOrientationRightMirrored: return UIImageOrientationRight; 
     default: return orientation; 
    } 
} 

Et utiliser la fonction comme ceci:

UIImage *flip = [UIImage imageWithCGImage:image.CGImage 
            scale:image.scale 
           orientation:mirroredImageOrientation(image.imageOrientation)]; 

J'ai ajouté des points d'interrogation pour indiquer le code douteux, nauséabond. Similaire à The Practice of Programming

+1

En fait, si votre réponse semble bonne, ce n'est pas dans tous les cas. par exemple. Si vous voulez faire un flip horizontal mais que votre orientation de l'image est Right, vous devez faire LeftMirrored, car RightMirrored donnera un retournement vertical. – AncAinu

+0

Passer de non-miroir à miroir reflétera horizontalement l'image, du point de vue de vous asseoir à votre place. (Vous avez raison de dire que du point de vue de l'image elle se retournera selon les annotations dans l'énumération.) Si les faces sont orientées dans la bonne direction (haut de la tête vers le haut de l'image), toutes les transformations miroir inversera cette face horizontalement (c'est-à-dire le long d'un axe vertical). Documentation pour UIImageOrientation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/c/tdef/UIImageOrientation. – sabalaba

+0

J'ai édité ma réponse pour suggérer d'utiliser une instruction switch explicite. Qui sait ce qui se passera sur la route. Peut-être que Apple va changer la commande de l'énumération, auquel cas la version arithmétique modulaire devient incorrecte. – sabalaba

5

Aucune des réponses ci-dessus, ne répond à la partie de la question qui reflète la moitié de l'image ne retournant pas l'image entière. Le mélange des solutions conduit à la fonction exemple suivant vous pouvez utiliser comme une catégorie telle que UIImage + Mirroring:

(UIImage *) horizontalMirror { 
    UIImageOrientation flippedOrientation = UIImageOrientationUpMirrored; 
    switch (self.imageOrientation) { 
     case UIImageOrientationUp: break; 
     case UIImageOrientationDown: flippedOrientation = UIImageOrientationDownMirrored; break; 
    } 
    UIImage * flippedImage = [UIImage imageWithCGImage:self.CGImage scale:1.0 orientation:flippedOrientation]; 

    CGImageRef inImage = self.CGImage; 
    CGContextRef ctx = CGBitmapContextCreate(NULL, 
              CGImageGetWidth(inImage), 
              CGImageGetHeight(inImage), 
              CGImageGetBitsPerComponent(inImage), 
              CGImageGetBytesPerRow(inImage), 
              CGImageGetColorSpace(inImage), 
              CGImageGetBitmapInfo(inImage) 
              ); 
    CGRect cropRect = CGRectMake(flippedImage.size.width/2, 0, flippedImage.size.width/2, flippedImage.size.height); 
    CGImageRef TheOtherHalf = CGImageCreateWithImageInRect(flippedImage.CGImage, cropRect); 
    CGContextDrawImage(ctx, CGRectMake(0, 0, CGImageGetWidth(inImage), CGImageGetHeight(inImage)), inImage); 

    CGAffineTransform transform = CGAffineTransformMakeTranslation(flippedImage.size.width, 0.0); 
    transform = CGAffineTransformScale(transform, -1.0, 1.0); 
    CGContextConcatCTM(ctx, transform); 

    CGContextDrawImage(ctx, cropRect, TheOtherHalf); 

    CGImageRef imageRef = CGBitmapContextCreateImage(ctx); 
    CGContextRelease(ctx); 
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 

    return finalImage; 
} 
+0

Merci ça a marché – ChanWarde