2010-06-27 11 views
15

? Estoy tratando de averiguar si hay alguna forma de duplicar una imagen. Por ejemplo, toma una foto de la cara de alguien y luego córtala por la mitad y muestra cómo se ve su cara con cada lado reflejado. No parece haber trucos como este en las funciones CGAffineTransform. Los expertos en gráficos por favor ayuda!¿Cómo puedo reflejar una imagen UIImage de UIImagePickerController

Respuesta

34

El "truco" básico aquí es usar una transformación de escala alrededor del eje X o Y con un factor de -1. Por ejemplo, podría utilizar esto para crear un "flip alrededor del eje horizontal" transformar:

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

entonces se puede establecer la propiedad transform en un UIImageView para voltear la imagen asignada, o concatena con otra transformada de hacer efectos más sofisticados. Para obtener el efecto exacto que describió, es posible que necesite escribir un código de dibujo personalizado para dibujar su imagen original en un contexto, luego superponga la mitad volteada encima de ella. Esto es relativamente sencillo en Core Graphics.

+4

o utilizar CGAffineTransformMakeScale es decir picker.cameraViewTransform = CGAffineTransformMakeScale (-1, 1) // rápida – khunshan

+1

excelente! Utilicé 'myImageView.transform = CGAffineTransformMakeScale (-1, 1);' –

19

Si sólo piensa en el apoyo 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

Usted puede pensar, ¿por qué molestarse con la instrucción switch exageradamente largo?

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

Y si se echa un vistazo a la enumeración se puede ver que la aritmética modular haría:

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

Pero este código es demasiado inteligente. En su lugar, debe escribir una función con una instrucción de cambio explícita. P.ej.

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

Y el uso de la función de la siguiente manera:

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

He añadido signos de interrogación para indicar el código cuestionable, maloliente. Similar a The Practice of Programming

+1

En realidad, si su respuesta parece buena, no es en todos los casos. p. si quieres hacer un giro horizontal pero tu orientación de la imagen es Derecha, tienes que hacer el Marcado Izquierdo, porque el DerechoMirrojo dará una vuelta vertical. – AncAinu

+0

Pasar de no reflejado a espejo reflejará horizontalmente la imagen, desde la perspectiva de que se siente en su asiento. (Tiene razón en que, desde la perspectiva de la imagen, se volteará de acuerdo con las anotaciones en la enumeración). Si las caras están orientadas en la dirección correcta (parte superior de la cabeza a la parte superior de la imagen), todas las transformaciones no reflejadas reflejado volteará esa cara horizontalmente (es decir, a lo largo de un eje vertical). Documentación para UIImageOrientation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/c/tdef/UIImageOrientation. – sabalaba

+0

Edité mi respuesta para sugerir el uso de una instrucción de cambio explícita. Quién sabe lo que sucederá en el futuro. Tal vez Apple cambie el orden de la enumeración en cuyo caso la versión aritmética modular se vuelve incorrecta. – sabalaba

5

Ninguna de las respuestas anteriores responde a la parte de la pregunta que refleja la mitad de la imagen sin voltear toda la imagen. La mezcla de las soluciones conduce a la siguiente función de ejemplo puede usar como una categoría como 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

Gracias funcionó – ChanWarde

Cuestiones relacionadas