Wie kann ich UIImage horizontal drehen?


111

Wie man das UIImagehorizontal umdreht, habe ich UIImageOrientationUpMirroredin der UIImageKlassenreferenz einen Aufzählungswert gefunden , wie man diese Eigenschaft zum Umdrehen verwendet UIImage.


Um die gute Antwort von aroth zu ergänzen, erklärt Apple die anderen Arten von Bildorientierungen unter diesem Link
coco

Da das Akzeptierte bei mir nicht funktionierte, fand ich diese Kategorie . Klappt wunderbar.
Dwbrito

Antworten:


237

Ziel c

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

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

Schnell

let flippedImage = myImage.withHorizontallyFlippedOrientation()

14
Bei dieser Antwort gibt es zwei Probleme: Die Skalierung ist bei Bildern mit Retina-Konkurrenz nicht 1,0 und hat aus irgendeinem Grund UIImageOrientationUpfunktioniert, UIImageOrientationUpMirroredohne sie umzudrehen . Dies funktionierte -image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp]
Kof

1
@Kof Wie ich bemerkt habe, wird der Orientierungsparameter, den Sie übergeben, verwendet, um zu bestimmen, wie die Ausrichtung des Quellbilds bereits ist, im Gegensatz zu "Geben Sie mir dieses Bild mit dieser spezifischen Ausrichtung". Daher können Sie den Parameter sourceImage.imageOrientation überprüfen und in einer anderen Ausrichtung übergeben, um die Methode auszutricksen und Ihnen das zu geben, was Sie möchten
Ege Akpinar

6
Es wäre besser, sourceImage.scalefür die Waage zu verwenden.
Sam Soffes

Wie geht das in Swift? [UIImage imageWithCGImage ...] ist dort nicht verfügbar.
Lim Thye Chean

3
Dies scheint völlig zu brechen, wenn ich es versuche [flippedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]. Irgendeine Idee warum?
devios1

70

Eine sehr einfache Möglichkeit, dies zu erreichen, besteht darin, eine UIImageView anstelle einer UIImage zu erstellen und die Transformation in UIImageView durchzuführen.

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

Hoffe das hilft.


2
Dies funktionierte für mich viel besser als die UIImageManipulation, die in Kombination mit dem UIImageRenderingModeAlwaysTemplateRendering-Modus Nebenwirkungen hatte .
devios1

2
Vielen Dank für das Teilen. Ich hatte kein Glück mit der "Antwort" auf dieses Rätsel, das mit diesem Beitrag verbunden ist, aber Ihre Antwort funktionierte phänomenal gut und bestand nur aus 1 Codezeile.
Adrian

Funktioniert super! iOS 9+ enthält jetzt auch flipsForRightToLeftLayoutDirection, funktioniert jedoch noch nicht für iOS 8+ Apps.

3
Wenn Sie das yourImageView.transform = CGAffineTransformIdentity
Umdrehen

Beachten Sie, dass diese Methode in UIImageView 'transformiert'. Das eigentliche UIImage wird nicht umgedreht.
Langsam

36

Ein vertikaler Flip ist häufig erforderlich, um die OpenGL-Textur mit zu initialisieren glTexImage2d(...). Die oben vorgeschlagenen Tricks ändern die Bilddaten nicht und funktionieren in diesem Fall nicht. Hier ist ein Code für den eigentlichen Datenwechsel, der von https://stackoverflow.com/a/17909372 inspiriert wurde

- (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
Wie funktioniert dieses Flipbild? Es sieht einfach so aus, als würde es das Bild wieder zeichnen.
Jonathan.

@ Jonathan. Ich denke, es dreht sich aufgrund unterschiedlicher Koordinatensysteme (dh Richtung der Y-Achse) beim Zeichnen.
Alexey Podlasov

Gibt es eine Möglichkeit, das Bild vertikal zu spiegeln?
Praxiteles

Diese Methode unterstützt auch das Rendern von
Bildern

3
Verwenden Sie UIGraphicsBeginImageContextWithOptions (image.size, NO, image.scale), um das Qualitätsproblem zu beheben. stattdessen.
Nick Lockwood

14

Ich habe versucht, mit imageFlippedForRightToLeftLayoutDirection ein neues UIImage mit unterschiedlichen Ausrichtungen zu erstellen, aber zumindest ist dies die einzige Lösung, die ich zum Spiegeln meines Bildes gefunden habe

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

Wie Sie auf meinem Spielplatz sehen können, hat es funktioniert !! :) :) Geben Sie hier die Bildbeschreibung ein

Und das sei natürlich finalImage = UIImage (CIImage: rotada3)


Sorry, aber das sieht so aus, als würde es nicht mehr funktionieren, zumindest mit Kameraaufnahmen ...
Oni_01

12

Wie es Bildorientierung definiert:

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

Ich habe einige Verbesserungen für weitere Umstände vorgenommen, z. B. für den Umgang mit UIImage aus 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

Hier ist eine schnelle Version: (Ich habe diese Frage in Kommentaren gesehen)

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

Dies ist eine solide Implementierung zum horizontalen Spiegeln / Spiegeln eines UIImage und kann auf das Bild hin und her angewendet werden. Da die zugrunde liegenden Bilddaten geändert werden, ändert sich auch die Zeichnung (z. B. Screenshot). Getestet, um zu arbeiten, kein Qualitätsverlust.

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

Möglicherweise ist dies für einige von Nutzen:

    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

Für Swift 3/4:

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

Dies ist für eine UIImageView, das OP sucht nach einer UIImage
Shizam

2

Eine einfache Erweiterung.

extension UIImage {

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

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

Verwendung:

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

Erweiterungen sind eine der besten Funktionen von Swift. Ich bin überrascht, dass die obigen ursprünglichen Antworten dies nicht empfehlen. Ich mag diese Version viel besser.
DS.

1

Dies ist eine funktionierende iOS8 / 9-kompatible Version:

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;

Ich denke nicht, dass dies die beste Idee ist. Dies imageFlippedForRightToLeftLayoutDirection soll mit gespiegelten Layoutanweisungen verwendet werden - zum Beispiel für arabische Länder. Daher funktioniert die Verwendung möglicherweise nicht immer wie gewünscht.
Peter Stajger

1
Ja, Sie haben Recht - in meinem Fall war es genau für die RTL-Unterstützung. Wir alle wissen, dass Code auf SO als Referenz dient und die Leute nicht wirklich nur kopieren / einfügen, ohne es vorher zu verstehen, oder?
Capikaw

1

Getestet in Swift 3 und höher

Hier ist die einfache Lösung, um dieses Problem mit Erweiterungen zu erreichen. Ich teste es und es hat funktioniert. Sie können in jede Richtung spiegeln.

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

Verwendung für diesen Code

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

Sie können also andere Funktionen verwenden.


0

Hier ist eine der oben modifizierten Antworten in Swift 3 , die ich besonders nützlich fand, wenn Sie eine Schaltfläche haben, die das Bild immer wieder hin und her drehen muss.

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)

    }

Verwenden:

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

0

Antwort von 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
Nur-Code-Antworten gelten im Allgemeinen als minderwertig. Erklären Sie zusätzlich zu Ihrem Code, wie / warum er funktioniert, beheben Sie das Problem oder beantworten Sie die Frage.
Chharvey

1
Dies funktioniert auch nicht für die OP-Frage, da er darum bittet, das Bild umzudrehen. Der Code hier dreht die Bildansicht um. Beide unterscheiden sich sehr darin, wo sie verwendet werden können. Beispiel: Eine Schaltfläche nimmt ein Bild auf, keine Bildansicht.
DS.

Außerdem haben Sie gerade meine Antwort kopiert und schnell 4
Shaked Sayag

0

Gehen Sie beim Auspacken wie folgt vor:

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

0

Sie können das Bild damit drehen, wie Sie möchten

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

Die beste Lösung für horizontales Drehen: Sehen Sie sich dieses Video an:

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

Oder verwenden Sie diesen Code:

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

}

Sie können in dieser Animation eine beliebige Benutzeroberfläche (Schaltfläche oder Beschriftung oder Ansicht oder Bild) verwenden.


1
Es wird nicht empfohlen, einen Link als Antwort zu veröffentlichen. Der Link könnte eines Tages ungültig werden. Wenn Sie der Meinung sind, dass die Methode hilfreich ist, können Sie sie bitte hier posten.
Christopher
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.