Come capovolgere UIImage orizzontalmente?


111

Come capovolgere UIImageorizzontalmente, ho trovato il UIImageOrientationUpMirroredvalore di enumerazione nel UIImageriferimento alla classe, come utilizzare questa proprietà per capovolgere UIImage.


Per aggiungere alla bella risposta di aroth, Apple spiega molto bene gli altri tipi di orientamenti dell'immagine a questo link
coco

Dato che l'accettato non funzionava per me, ho trovato questa categoria . Funziona come un fascino.
dwbrito

Risposte:


238

Objective-C

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

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

veloce

let flippedImage = myImage.withHorizontallyFlippedOrientation()

14
Ci sono due problemi con questa risposta: la scala non è 1.0 per le immagini compatibili con la retina e per qualche motivo ha UIImageOrientationUpfunzionato UIImageOrientationUpMirroredsenza capovolgerla. Ha funzionato -image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp]
Kof

1
@Kof come ho notato, il parametro di orientamento che passi viene utilizzato per determinare "qual è già l'orientamento di sourceImage" invece di "dammi questa immagine con questo orientamento specifico". Quindi, puoi ispezionare il parametro sourceImage.imageOrientation e passare con un orientamento diverso per ingannare il metodo per darti quello che vuoi
Ege Akpinar

6
Sarebbe meglio usare sourceImage.scaleper la bilancia.
Sam Soffes

Come farlo in Swift? [UIImage imageWithCGImage ...] non è disponibile lì.
Lim Thye Chean

3
Questo sembra rompersi completamente quando provo a farlo [flippedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]. Qualche idea sul perché?
devios1

70

Un modo molto semplice per ottenere ciò è creare un UIImageView invece di un UIImage ed eseguire la trasformazione su UIImageView.

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

Spero che questo ti aiuti.


2
Questo ha finito per funzionare molto meglio per me rispetto alla UIImagemanipolazione, che ho trovato aveva effetti collaterali se combinata con UIImageRenderingModeAlwaysTemplatela modalità di rendering.
devios1

2
Grazie per aver condiviso questo. Non ho avuto fortuna con la "risposta" a questo puzzle associata a questo post, ma la tua risposta ha funzionato straordinariamente bene ed era solo una riga di codice.
Adrian

Funziona alla grande! iOS 9+ ora include anche flipsForRightToLeftLayoutDirection, ma non funzionerà ancora per le app iOS 8+.

3
Se vuoi reimpostare il lancio, usayourImageView.transform = CGAffineTransformIdentity
chanil

Nota che questo metodo "trasforma" su UIImageView. Non capovolge l'effettivo UIImage.
lento

36

Il capovolgimento verticale è spesso necessario per inizializzare la trama OpenGL usando glTexImage2d(...). I trucchi proposti sopra non modificano effettivamente i dati dell'immagine e in questo caso non funzioneranno. Ecco un codice per eseguire l'effettivo capovolgimento dei dati ispirato a 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
Come funziona questa immagine capovolta? Sembra solo che disegna di nuovo l'immagine.
Jonathan.

@Jonathan. Penso che si ribalti a causa di diversi sistemi di coordinate (cioè direzione dell'asse Y) durante il disegno.
Alexey Podlasov

C'è un modo per usarlo per capovolgere l'immagine verticalmente?
Prassitele

questo metodo supporta bene anche il rendering delle immagini - sempre template
Peter Stajger

3
Per risolvere il problema di qualità, utilizzare UIGraphicsBeginImageContextWithOptions (image.size, NO, image.scale); anziché.
Nick Lockwood

14

Ho provato con imageFlippedForRightToLeftLayoutDirection e creando un nuovo UIImage con orientamenti diversi ma almeno questa è l'unica soluzione che ho trovato per capovolgere la mia immagine

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

Come puoi vedere nel mio parco giochi ha funzionato !! :) inserisci qui la descrizione dell'immagine

E, ovviamente, lascia finalImage = UIImage (CIImage: rotada3)


Scusa ma sembra che non
funzioni

12

Come definisce l'orientamento dell'immagine:

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

Ho apportato alcuni miglioramenti per più circostanze come la gestione di UIImage da 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

ecco la versione rapida: (Ho visto questa domanda nei commenti)

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

8

iOS 10+

[myImage imageWithHorizontallyFlippedOrientation];

Swift 4:

let flippedImage = myImage.withHorizontallyFlippedOrientation()

7

Questa è un'implementazione solida per specchiare / capovolgere orizzontalmente un UIImage e può essere applicato all'immagine avanti e indietro. Poiché cambia i dati dell'immagine sottostante, cambierà anche il disegno (come, screenshot). Testato per funzionare, nessuna perdita di qualità.

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

Potrebbe essere utile per alcuni:

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

5

Per Swift 3/4:

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

Questo è per un UIImageView, l'OP sta cercando un UIImage
Shizam

2

Una semplice estensione.

extension UIImage {

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

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

Uso:

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

Le estensioni sono una delle migliori caratteristiche di Swift. Sono sorpreso che le risposte originali sopra non siano riuscite a consigliarlo. Mi piace molto di più questa versione.
DS.

1

Questa è una versione compatibile con iOS8 / 9 funzionante:

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;

Non credo che questa sia l'idea migliore. Questo imageFlippedForRightToLeftLayoutDirection è pensato per essere utilizzato con le direzioni di layout capovolte, ad esempio per i paesi arabi. Quindi l'utilizzo di questo potrebbe non funzionare sempre come desiderato.
Peter Stajger,

1
Sì, hai ragione: nel mio caso era esattamente per il supporto RTL. Sappiamo tutti che il codice su SO è di riferimento e le persone non si limitano a copiare / incollare senza prima capirlo, giusto?
capikaw

1

Testato in Swift 3 e versioni successive

Ecco la semplice soluzione per risolvere questo problema con le estensioni. L'ho provato e ha funzionato. Puoi specchiarti in qualsiasi direzione.

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

Utilizzo per questo codice

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

Quindi, puoi usare altre funzioni.


0

Ecco una delle risposte sopra modificate e in Swift 3 che ho trovato particolarmente utile quando hai un pulsante che deve continuare a girare l'immagine avanti e indietro.

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)

    }

Uso:

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

0

la risposta di aroth in SWIFT 3:

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

0

Swift 4

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

3
Le risposte di solo codice sono generalmente considerate di bassa qualità. Oltre al codice, spiega come / perché funziona, risolve il problema o risponde alla domanda.
chharvey

1
Inoltre, questo non funziona per la domanda OP, poiché chiede di capovolgere l'immagine. Il codice qui capovolge la visualizzazione dell'immagine. Entrambi sono molto diversi in termini di dove possono essere utilizzati. ad esempio, un pulsante acquisisce un'immagine non una visualizzazione immagine.
DS.

Inoltre, hai appena copiato la mia risposta e hai scritto swift 4
Shaked Sayag

0

A causa dello scartamento, eseguire le seguenti operazioni:

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

0

puoi ruotare l'immagine come vuoi usando questo

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

Swift 5 - Xcode 11.5

La migliore soluzione per ruotare orizzontalmente: guarda questo video:

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

Oppure usa questo codice:

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

}

È possibile utilizzare qualsiasi interfaccia utente (pulsante o etichetta o vista utente o immagine) in questa animazione.


1
Non è consigliabile pubblicare un collegamento come risposta. Il collegamento potrebbe diventare non valido un giorno. Se ritieni che il metodo sia utile, potresti pubblicarlo qui?
Christopher
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.