Як перевернути 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.