Как зеркалировать изображение 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;
}