2010-06-27 3 views
15

Я пытаюсь выяснить, есть ли способ отразить изображение. Например, сфотографируйте чье-то лицо, а затем разрежьте его пополам и покажите, как выглядит их лицо, с каждой стороны зеркально. Кажется, в функциях CGAffineTransform подобных трюков нет. Графические эксперты, пожалуйста, помогите !!!Как зеркалировать изображение UIImage от UIImagePickerController

ответ

34

Основным «трюком» здесь является использование масштабирующего преобразования вокруг оси X или Y с коэффициентом -1. Например, вы могли бы использовать это, чтобы создать «флип вокруг горизонтальной оси» преобразование:

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

Затем вы можете установить transform свойства на UIImageView переворачивать назначенное изображение или сцепить его с другим преобразование сделать более сложные эффекты. Чтобы получить точный эффект, который вы описали, вам может потребоваться написать какой-то пользовательский код рисования, чтобы нарисовать исходное изображение в контексте, а затем наложить перевернутую половину поверх него. Это относительно просто в Core Graphics.

+4

или использовать CGAffineTransformMakeScale т.е. picker.cameraViewTransform = CGAffineTransformMakeScale (-1, 1) // скор – khunshan

+1

Отлично! Я использовал 'myImageView.transform = CGAffineTransformMakeScale (-1, 1);' –

19

Если вы только планируете поддерживать 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

Вы можете подумать, почему заморачиваться с возмутительно длинным заявлением переключатель?

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

И если вы посмотрите на перечисление вы можете увидеть, что модульная арифметика бы:

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

Но этот код слишком умен. Вместо этого вы должны написать функцию с явным оператором switch. Например.

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

И использовать функцию вроде этого:

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

я добавил вопросительные знаки для обозначения сомнительного, вонючий кода. Подобно The Practice of Programming

+1

На самом деле, если ваш ответ кажется хорошим, это не во всех случаях. , например. если вы хотите сделать горизонтальный флип, но ваша ориентация изображения правильная, вам нужно сделать LeftMirrored, потому что RightMirrored даст вертикальный флип. – AncAinu

+0

Переход от не зеркального отражения будет горизонтально отражать изображение, с точки зрения вас, сидящего на вашем месте. (Вы правы, что с точки зрения самого изображения он будет переворачиваться в соответствии с аннотациями в перечислении.) Если лица ориентированы в правильном направлении (верхняя часть головы до верхней части изображения), тогда все преобразования от незеркализованных до зеркальная будет переворачивать эту грань горизонтально (то есть вдоль вертикальной оси). Документация для UIImageOrientation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/c/tdef/UIImageOrientation. – sabalaba

+0

Я отредактировал свой ответ, чтобы предложить использование явного оператора switch. Кто знает, что произойдет в будущем. Возможно, Apple изменит порядок перечисления, и в этом случае модульная арифметическая версия станет неправильной. – sabalaba

5

Ни один из ответов выше, ответьте на часть вопроса, которая отражает половину изображения, не переворачивая изображение целиком. Смешивание растворов приводит к следующей функции образца вы можете использовать в качестве категории, такие как UIImage + Зеркалирование:

(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

Спасибо, что сработало – ChanWarde

Смежные вопросы