Як перевернути UIImage горизонтально?


111

Як перевернути UIImageгоризонтально, я знайшов UIImageOrientationUpMirroredзначення перерахунку в UIImageдовіднику класу, як використовувати цю властивість для перевертання UIImage.


Щоб додати точну відповідь на aroth, Apple дуже добре пояснює інші типи орієнтації зображень за цим посиланням
— coco

Оскільки прийняте не працювало для мене, я знайшов цю категорію . Працює як шарм.
— dwbrito

Відповіді:


238

Ціль-С

UIImage* sourceImage = [UIImage imageNamed:@"whatever.png"];

UIImage* flippedImage = [UIImage imageWithCGImage:sourceImage.CGImage 
                                            scale:sourceImage.scale
                                      orientation:UIImageOrientationUpMirrored];

Швидкий

let flippedImage = myImage.withHorizontallyFlippedOrientation()

14
Є дві проблеми з цією відповіддю - масштаб не 1,0 на знімках, що змагаються на сітківці, і чомусь UIImageOrientationUpпрацював, поки UIImageOrientationUpMirroredне гортав його. Це спрацювало -image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp]
— Коф

1
@ Як я помітив, параметр орієнтації, який ви передаєте, використовується для визначення "того, що орієнтація sourceImage вже є", а не "дати мені це зображення з цією конкретною орієнтацією". Отже, ви можете перевірити параметр sourceImage.imageOrientation та передати іншу орієнтацію, щоб обманути метод, щоб дати вам те, що ви хочете
— Еге Акпінар

6
Краще було б використовувати sourceImage.scaleдля шкали.
— Сем Софф

Як це зробити в Swift? [UIImage imageWithCGImage ...] там недоступний.
— Lim Thye Chean

3
Це, здається, повністю зламається, коли я намагаюся це зробити [flippedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]. Будь-яка ідея чому?
— devios1

70

Дуже простий спосіб досягти цього - створивши UIImageView замість UIImage та виконати перетворення на UIImageView.

yourImageView.image =[UIImage imageNamed:@"whatever.png"];
yourImageView.transform = CGAffineTransform(scaleX: -1, y: 1); //Flipped

Сподіваюся, це допомагає.


2
Це закінчилося для мене набагато краще, ніж UIImageманіпуляції, які, як я виявив, мали побічні ефекти в поєднанні з UIImageRenderingModeAlwaysTemplateрежимом візуалізації.
— devios1

2
Дякуємо, що поділилися цим. Мені не пощастило з "відповіддю" на цю загадку, пов’язану з цією публікацією, але ваша відповідь спрацювала феноменально добре і була лише 1 рядок коду.
— Адріан

Чудово працює! Тепер iOS 9+ також включає в себе flipsForRightToLeftLayoutDirection, але він ще не працюватиме для додатків iOS 8+.

3
Якщо ви хочете скинути yourImageView.transform = CGAffineTransformIdentity
— фліппінг

Зауважте, що цей метод "перетворюється" на UIImageView. Він не перевертає фактичний UIImage.
— повільно

36

Вертикальний фліп часто потрібен для ініціалізації текстури OpenGL за допомогою glTexImage2d(...). Запропоновані вище трюки насправді не змінюють дані зображення і в цьому випадку не працюватимуть. Ось код для того, щоб зробити фактичний фліп даних, натхненний https://stackoverflow.com/a/17909372

- (UIImage *)flipImage:(UIImage *)image
{
    UIGraphicsBeginImageContext(image.size);
    CGContextDrawImage(UIGraphicsGetCurrentContext(),CGRectMake(0.,0., image.size.width, image.size.height),image.CGImage);
    UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return i;
}

1
Як це перевернути зображення? Це просто схоже на те, що він знову малює зображення.
— Джонатан.

@Jonathan. Я думаю, що він перевертається через різні системи координат (тобто напрямок осі Y) під час малювання.
— Олексій Підласов

Чи є спосіб використовувати це для перевертання зображення по вертикалі?
— Праксителес

цей метод чудово підтримує також візуалізацію зображень - завжди шаблон
— Пітер Штайгер

3
Щоб вирішити проблему якості, використовуйте UIGraphicsBeginImageContextWithOptions (image.size, NO, image.scale); замість цього.
— Нік Локвуд

14

Я спробував за допомогою imageFlippedForRightToLeftLayoutDirection та створив новий UIImage з різними орієнтаціями, але принаймні це єдине рішення, яке я знайшов для гортання свого зображення

let ciimage: CIImage = CIImage(CGImage: imagenInicial.CGImage!)
let rotada3 = ciimage.imageByApplyingTransform(CGAffineTransformMakeScale(-1, 1))

Як ви бачите, на моєму майданчику це працювало !! :) введіть тут опис зображення

І, звичайно, нехай finalImage = UIImage (CIImage: rotada3)


Вибачте, але це, схоже, більше не працює, принаймні з фотографіями, зробленими фотоапаратом ...
— Oni_01,

12

Орієнтація зображення визначає:

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

Я вніс деякі вдосконалення для інших обставин, таких як обробка UIImage від AVCaptureSession.

UIImage* sourceImage = [UIImage imageNamed:@"whatever.png"];
UIImageOrientation flipingOrientation;
if(sourceImage.imageOrientation>=4){
    flippedOrientation = sourceImage.imageOrientation - 4;
}else{
    flippedOrientation = sourceImage.imageOrientation + 4;
}
UIImage* flippedImage = [UIImage imageWithCGImage:sourceImage.CGImage 
                     scale: sourceImage.scale orientation: flipingOrientation];

9

ось швидка версія: (це питання я бачив у коментарях)

let srcImage = UIImage(named: "imageName")
let flippedImage = UIImage(CGImage: srcImage.CGImage, scale: srcImage.scale, orientation: UIImageOrientation.UpMirrored)


7

Це суцільна реалізація для дзеркального / перегортання UIImage горизонтально, і може застосовуватися до зображення вперед і назад. Оскільки він змінює основні дані зображення, малюнок (наприклад, скріншот) також зміниться. Випробуваний на роботі, втрат якості немає.

func flipImage() -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let bitmap = UIGraphicsGetCurrentContext()!

        bitmap.translateBy(x: size.width / 2, y: size.height / 2)
        bitmap.scaleBy(x: -1.0, y: -1.0)

        bitmap.translateBy(x: -size.width / 2, y: -size.height / 2)
        bitmap.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image?
}

5

Це може бути корисно для деяких:

    UIImageOrientation imageOrientation;

    switch (sourceImage.imageOrientation) {
        case UIImageOrientationDown:
            imageOrientation = UIImageOrientationDownMirrored;
            break;

        case UIImageOrientationDownMirrored:
            imageOrientation = UIImageOrientationDown;
            break;

        case UIImageOrientationLeft:
            imageOrientation = UIImageOrientationLeftMirrored;
            break;

        case UIImageOrientationLeftMirrored:
            imageOrientation = UIImageOrientationLeft;

            break;

        case UIImageOrientationRight:
            imageOrientation = UIImageOrientationRightMirrored;

            break;

        case UIImageOrientationRightMirrored:
            imageOrientation = UIImageOrientationRight;

            break;

        case UIImageOrientationUp:
            imageOrientation = UIImageOrientationUpMirrored;
            break;

        case UIImageOrientationUpMirrored:
            imageOrientation = UIImageOrientationUp;
            break;
        default:
            break;
    }

    resultImage = [UIImage imageWithCGImage:sourceImage.CGImage scale:sourceImage.scale orientation:imageOrientation];


2

Просте розширення.

extension UIImage {

    var flipped: UIImage {
        guard let cgImage = cgImage else {
            return self
        }

        return UIImage(cgImage: cgImage, scale: scale, orientation: .upMirrored)
    }
}

Використання:

let image = #imageLiteral(resourceName: "imageName")
let imageView = UIImageView(image: image.flipped)

Розширення - одна з найкращих особливостей Swift. Я здивований, що оригінальні відповіді вище не змогли цього рекомендувати. Мені ця версія подобається набагато краще.
— ДС.

1

Це працююча версія iOS8 / 9:

UIImage *image = [UIImage imageNamed:name];

if ([[UIApplication sharedApplication] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft) {

    if ([image respondsToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)]) {
        //iOS9
        image = image.imageFlippedForRightToLeftLayoutDirection;
    }
    else {
        //iOS8
        CIImage *coreImage = [CIImage imageWithCGImage:image.CGImage];
        coreImage = [coreImage imageByApplyingTransform:CGAffineTransformMakeScale(-1, 1)];
        image = [UIImage imageWithCIImage:coreImage scale:image.scale orientation:UIImageOrientationUp];
    }
}

return image;

Я не думаю, що це найкраща ідея. Це imageFlippedForRightToLeftLayoutDirection призначено для використання у напрямку перевернутого макета - наприклад, для арабських країн. Тож використання цього може не завжди працювати так, як бажано.
— Пітер Штайгер

1
Так, ви маєте рацію - в моєму випадку саме для підтримки RTL. Ми всі знаємо, що код на SO є довідковим, і люди насправді не просто копіюють / вставляють, не розуміючи його спочатку, правда?
— capikaw

1

Випробувано в Swift 3 і вище

Ось просте рішення для досягнення цієї проблеми за допомогою розширень. Я тестую це, і воно спрацювало. Ви можете дзеркала в будь-якому напрямку.

extension UIImage {

    func imageUpMirror() -> UIImage {
        guard let cgImage = cgImage else { return self }
        return UIImage(cgImage: cgImage, scale: scale, orientation: .upMirrored)
    }

    func imageDownMirror() -> UIImage {
        guard let cgImage = cgImage else { return self }
        return UIImage(cgImage: cgImage, scale: scale, orientation: .downMirrored)
    }

    func imageLeftMirror() -> UIImage {
        guard let cgImage = cgImage else { return self }
        return UIImage(cgImage: cgImage, scale: scale, orientation: .leftMirrored)
    }

    func imageRightMirror() -> UIImage {
        guard let cgImage = cgImage else { return self }
        return UIImage(cgImage: cgImage, scale: scale, orientation: .rightMirrored)
    }
}

Використання цього коду

let image = #imageLiteral(resourceName: "imageName")
flipHorizontally = image.imageUpMirror()

Отже, ви можете використовувати інші функції.


0

Ось один із відповідей, змінених вище, і в Swift 3, що мені здається особливо корисною, коли у вас є кнопка, яка повинна тримати гортання зображення вперед і назад.

func flipImage(sourceImage: UIImage,orientation: UIImageOrientation) -> UIImage {


        var imageOrientation = orientation

        switch sourceImage.imageOrientation {

        case UIImageOrientation.down:
            imageOrientation = UIImageOrientation.downMirrored;
            break;

        case UIImageOrientation.downMirrored:
            imageOrientation = UIImageOrientation.down;
            break;

        case UIImageOrientation.left:
            imageOrientation = UIImageOrientation.leftMirrored;
            break;

        case UIImageOrientation.leftMirrored:
            imageOrientation = UIImageOrientation.left;

            break;

        case UIImageOrientation.right:
            imageOrientation = UIImageOrientation.rightMirrored;

            break;

        case UIImageOrientation.rightMirrored:
            imageOrientation = UIImageOrientation.right;

            break;

        case UIImageOrientation.up:
            imageOrientation = UIImageOrientation.upMirrored;
            break;

        case UIImageOrientation.upMirrored:
            imageOrientation = UIImageOrientation.up;
            break;


        }


        return UIImage(cgImage: sourceImage.cgImage!, scale: sourceImage.scale, orientation: imageOrientation)

    }

Використання:

imageToFlip: UIImage = flipImage(sourceImage: imageToFlip, orientation: imageToFlip.imageOrientation)

0

відповідь aroth у SWIFT 3:

let sourceImage = UIImage(named: "whatever.png")!
let flippedImage = UIImage(cgImage: sourceImage.cgImage!, scale: sourceImage.scale, orientation: .upMirrored)

0

Швидкий 4

yourImage.transform = CGAffineTransform(scaleX: -1, y: 1)

3
Відповіді, що стосуються лише коду, зазвичай вважаються неякісними. Окрім свого коду, поясніть, як / чому він працює, виправляє проблему чи відповідає на питання.
— chharvey

1
Крім того, це не працює для питання про ОП, оскільки він просить перевернути зображення. Код тут гортає зображення зображення. Обидва дуже відрізняються з точки зору того, де їх можна використовувати. наприклад, кнопка знімає зображення, а не зображення.
— ДС.

Також ви просто скопіювали мою відповідь і написали стрімкий 4
— Shaked Sayag

0

Через розгортання виконайте наступне:

let srcImage = UIImage(named: "myimage")!
let flippedImage = UIImage(cgImage: srcImage.cgImage!, 
                   scale: srcImage.scale, orientation: UIImage.Orientation.upMirrored)

0

ви можете обертати зображення так, як вам потрібно

SWIFT 4

extension UIImage {
public func imageRotatedByDegrees(degrees: CGFloat, flip: Bool) -> UIImage {
    let radiansToDegrees: (CGFloat) -> CGFloat = {
        return $0 * (180.0 / CGFloat(M_PI))
    }
    let degreesToRadians: (CGFloat) -> CGFloat = {
        return $0 / 180.0 * CGFloat(M_PI)
    }

    // calculate the size of the rotated view's containing box for our drawing space
    let rotatedViewBox = UIView(frame: CGRect(origin: CGPoint.zero, size: size))
    let t = CGAffineTransform(rotationAngle: degreesToRadians(degrees));
    rotatedViewBox.transform = t
    let rotatedSize = rotatedViewBox.frame.size

    // Create the bitmap context
    UIGraphicsBeginImageContext(rotatedSize)
    let bitmap = UIGraphicsGetCurrentContext()!

    bitmap.translateBy(x: rotatedSize.width / 2.0, y: rotatedSize.height / 2.0)
    // Move the origin to the middle of the image so we will rotate and scale around the center.
    //CGContextTranslateCTM(bitmap, rotatedSize.width / 2.0, rotatedSize.height / 2.0);

    //   // Rotate the image context
    bitmap.rotate(by: degreesToRadians(degrees))
   // CGContextRotateCTM(bitmap, degreesToRadians(degrees));

    // Now, draw the rotated/scaled image into the context
    var yFlip: CGFloat

    if(flip){
        yFlip = CGFloat(-1.0)
    } else {
        yFlip = CGFloat(1.0)
    }
    bitmap.scaleBy(x: yFlip, y: -1.0)
    //CGContextScaleCTM(bitmap, yFlip, -1.0)
    bitmap.draw(self.cgImage!, in: CGRect.init(x: -size.width / 2, y: -size.height / 2, width: size.width, height: size.height))
   // CGContextDrawImage(bitmap, CGRectMake(-size.width / 2, -size.height / 2, size.width, size.height), CGImage)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    return newImage
}

}


0

Швидкий 5 - Xcode 11.5

Найкраще рішення для обертання по горизонталі: дивіться це відео:

https://m.youtube.com/watch?v=4kSLbuB-MlU

Або скористайтеся цим кодом:

    
import UIKit
class FirstViewControl: UIViewController {
    @IBOutlet weak var buttonAnim: UIButton!

    @IBAction func ClickOnButtonAnim(_ sender: UIButton) {    
        UIView.transition(with: buttonAnim, duration: 0.4, options: .transitionFlipFromLeft, animation: nil , completion: nil)
    }

}

У цій анімації ви можете використовувати будь-який інтерфейс користувача (кнопку або мітку, uiview або зображення).


1
Не рекомендується розміщувати посилання як відповідь. Посилання може стати недійсним через день. Якщо ви вважаєте, що метод корисний, чи можете ви опублікувати його тут?
— Крістофер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.