2010-06-27 5 views
15

Próbuję dowiedzieć się, czy jest jakiś sposób, aby odzwierciedlić obraz. Na przykład zrób zdjęcie czyjejś twarzy, a następnie podziel ją na pół i pokaż, jak wygląda ich twarz z lustrzanym odbiciem. Wydaje się, że nie ma żadnych takich sztuczek w funkcjach CGAffineTransform. Eksperci od grafiki pomóżcie !!!Jak lustro obraz UIImage z UIImagePickerController

Odpowiedz

34

Podstawowa „Trick” jest tu użyć skalowania przekształcić o osi X lub Y z współczynnik -1. Na przykład, można to wykorzystać, aby stworzyć „flip o osi poziomej” transform:

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

Następnie można ustawić właściwość transform na UIImageView odwrócić przypisany obraz, lub łączenia go z innym przekształcić zrobić bardziej wyrafinowane efekty. Aby uzyskać dokładnie opisany efekt, konieczne może być napisanie niestandardowego kodu rysunkowego w celu narysowania oryginalnego obrazu w kontekście, a następnie nałożenia na niego odwróconej połówki. Jest to stosunkowo proste w Core Graphics.

+4

, lub CGAffineTransformMakeScale tj picker.cameraViewTransform CGAffineTransformMakeScale = (1, 1) // szybki – khunshan

+1

Doskonała! Użyłem 'myImageView.transform = CGAffineTransformMakeScale (-1, 1);' –

19

Jeśli tylko plan na wspieraniu 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

można pomyśleć, co się męczyć z skandalicznie długi switch?

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

A jeśli spojrzeć na wyliczenia widać, że arytmetyka modularna zrobi:

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

Ale ten kod jest zbyt mądre. Powinieneś zamiast tego napisać funkcję z jawnym poleceniem switch. Na przykład.

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

i korzystać z funkcji takich jak to:

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

Dodałem znaki zapytania, aby wskazać wątpliwe, śmierdząca kod. Podobny do The Practice of Programming

+1

Właściwie, jeśli twoja odpowiedź wydaje się dobra, nie jest tak w każdym przypadku. np. jeśli chcesz wykonać poziomą klapkę, ale twoja orientacja obrazu jest prawidłowa, musisz zrobić LeftMirrored, bo RightMirrored da pionową klapkę. – AncAinu

+0

Przechodzenie od niepozornego lustra do odbicia lustrzanego spowoduje odbicie lustrzane w poziomie, z perspektywy siedzącej u Ciebie siedzącej. (Masz rację, że z perspektywy samego obrazu zostanie odwrócona zgodnie z adnotacjami w wyliczeniu.) Jeśli twarze są zorientowane we właściwym kierunku (od góry głowy do góry obrazu), to wszystkie przekształcenia od niepiłuszonego do odbicie lustrzane odwróci tę twarz poziomo (tj. wzdłuż pionowej osi). Dokumentacja dla UIImageOrientation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/c/tdef/UIImageOrientation. – sabalaba

+0

Edytowałem swoją odpowiedź, aby zasugerować użycie wyraźnej instrukcji switch. Kto wie, co stanie się w drodze. Może Apple zmieni porządek wyliczenia, w którym to przypadku modularna wersja arytmetyczna stanie się niepoprawna. – sabalaba

5

Żadna z powyższych odpowiedzi nie jest odpowiedzią na część pytania, która odzwierciedla dublowanie połowy obrazu, nie odwracając całego obrazu. Mieszanie roztworów prowadzi do następującej funkcji próbki można wykorzystać w takiej kategorii jak UIImage + Replika:

(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

Dzięki temu zadziałało – ChanWarde