Как мне отразить изображение UIImage из UIImagePickerController - PullRequest
15 голосов
/ 28 июня 2010

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

Ответы [ 6 ]

37 голосов
/ 28 июня 2010

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

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

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

19 голосов
/ 28 июня 2010

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

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

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

И если вы посмотрите на перечисление, вы увидите, что модульная арифметика будет делать:1006 * Но этот код слишком умный.Вместо этого вы должны написать функцию с явным оператором 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)];

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

5 голосов
/ 27 января 2014

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

Проще всего использовать:

UIImage(assetIdentifier: .myIcon)?.withHorizontallyFlippedOrientation()
0 голосов
/ 21 февраля 2019

Вы можете использовать код ниже для Swift 4.0

 func didTakePicture(_ real_image: UIImage) {
   //suppose real_image = :)
 var flipped_image = UIImage(CGImage: real_image.CGImage!, scale: real_image.scale, orientation: .leftMirrored)
  // flipped_image is  (:
  }
...