Как зеркалировать изображение UIImage от UIImagePickerController

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

Ответы

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

? 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)];

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

Ответ 4

Ни один из ответов выше, ответьте на часть вопроса, которая отражает половину изображения, не переворачивая все изображение. Смешивание решений приводит к следующей функции выборки, которую вы можете использовать в качестве категории, например 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;
}