Bagaimana cara membalik UIImage secara horizontal?


111

Cara membalikkan UIImagesecara horizontal, saya menemukan UIImageOrientationUpMirrorednilai pencacahan di UIImagereferensi kelas, bagaimana menggunakan properti ini untuk membalik UIImage.


Untuk menambah jawaban bagus aroth, Apple menjelaskan jenis orientasi gambar lainnya dengan sangat baik di tautan ini
coco

Karena diterima tidak berhasil untuk saya, saya menemukan kategori ini . Bekerja seperti pesona.
dwbrito

Jawaban:


238

Objective-C

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

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

Cepat

let flippedImage = myImage.withHorizontallyFlippedOrientation()

14
Ada dua masalah dengan jawaban ini - skala bukan 1,0 pada gambar yang dapat diterima retina dan untuk beberapa alasan UIImageOrientationUpberhasil sementara UIImageOrientationUpMirroredtidak membaliknya. Ini berhasil -image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp]
Kof

1
@Kof seperti yang saya perhatikan, parameter orientasi yang Anda berikan digunakan untuk menentukan 'apa orientasi sourceImage sudah' sebagai lawan dari 'beri saya gambar ini dengan orientasi khusus ini'. Oleh karena itu, Anda dapat memeriksa parameter sourceImage.imageOrientation dan meneruskan orientasi yang berbeda untuk mengelabui metode agar memberikan apa yang Anda inginkan
Ege Akpinar

6
Akan lebih baik jika digunakan sourceImage.scaleuntuk skala.
Sam Soffes

Bagaimana melakukan ini di Swift? [UIImage imageWithCGImage ...] tidak tersedia di sana.
Lim Thye Chean

3
Ini sepertinya benar-benar rusak ketika saya mencoba melakukannya [flippedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]. Tahu kenapa?
devios1

70

Cara yang sangat sederhana untuk mencapainya adalah dengan membuat UIImageView sebagai ganti UIImage dan melakukan transformasi pada UIImageView.

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

Semoga ini membantu.


2
Ini akhirnya bekerja jauh lebih baik bagi saya daripada UIImagemanipulasi, yang menurut saya memiliki efek samping saat dikombinasikan dengan UIImageRenderingModeAlwaysTemplatemode rendering.
devios1

2
Terima kasih telah membagikan ini. Saya tidak beruntung dengan "jawaban" untuk teka-teki yang terkait dengan posting ini, tetapi jawaban Anda bekerja dengan sangat baik dan hanya berupa 1 baris kode.
Adrian

Bekerja dengan baik! iOS 9+ sekarang juga menyertakan flipsForRightToLeftLayoutDirection, tetapi belum berfungsi untuk aplikasi iOS 8+.

3
Jika Anda ingin menyetel ulang yourImageView.transform = CGAffineTransformIdentity
pembalikan

Perhatikan metode ini 'mengubah' di UIImageView. Itu tidak membalik gambar UII yang sebenarnya.
lambat

36

Flip vertikal sering kali diperlukan untuk menginisialisasi tekstur OpenGL menggunakan glTexImage2d(...). Trik yang diusulkan di atas tidak benar-benar mengubah data gambar dan tidak akan berfungsi dalam kasus ini. Berikut adalah kode untuk melakukan flip data aktual yang terinspirasi oleh 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
Bagaimana gambar flip ini? Sepertinya itu menarik gambar lagi.
Jonathan.

@Jonathan. Saya pikir itu membalik karena sistem koordinat yang berbeda (yaitu arah sumbu Y) saat menggambar.
Alexey Podlasov

Apakah ada cara untuk menggunakan ini untuk membalik gambar secara vertikal?
Praxiteles

metode ini dengan baik mendukung juga rendering gambar - selalu template
Peter Stajger

3
Untuk memperbaiki masalah kualitas, gunakan UIGraphicsBeginImageContextWithOptions (image.size, NO, image.scale); sebagai gantinya.
Nick Lockwood

14

Saya telah mencoba dengan imageFlippedForRightToLeftLayoutDirection, dan membuat UIImage baru dengan orientasi yang berbeda tetapi setidaknya ini adalah satu-satunya solusi yang saya temukan untuk membalik gambar saya

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

Seperti yang Anda lihat di taman bermain saya, itu berhasil !! :) masukkan deskripsi gambar di sini

Dan, tentu saja, biarkan finalImage = UIImage (CIImage: rotada3)


Maaf tapi sepertinya ini sudah tidak berfungsi lagi, setidaknya dengan kamera yang diambil gambar ...
Oni_01

12

Seperti yang didefinisikan oleh Orientasi Gambar:

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

Saya membuat beberapa perbaikan untuk lebih banyak keadaan seperti menangani UIImage dari 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

inilah versi cepat: (Saya melihat pertanyaan ini di komentar)

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

8

iOS 10+

[myImage imageWithHorizontallyFlippedOrientation];

Cepat 4:

let flippedImage = myImage.withHorizontallyFlippedOrientation()

7

Ini adalah implementasi yang solid untuk mencerminkan / membalik gambar UII secara horizontal, dan dapat diterapkan ke gambar bolak-balik. Karena itu mengubah data gambar yang mendasarinya, gambar (seperti, tangkapan layar) juga akan berubah. Teruji bekerja, tidak ada penurunan kualitas.

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

Mungkin ini akan berguna untuk beberapa:

    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

Untuk Swift 3/4:

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

Ini untuk UIImageView, OP mencari UIImage
Shizam

2

Perpanjangan sederhana.

extension UIImage {

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

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

Pemakaian:

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

Ekstensi adalah salah satu fitur terbaik Swift. Saya terkejut bahwa jawaban asli di atas gagal merekomendasikan hal itu. Saya menyukai versi ini jauh lebih baik.
DS.

1

Ini adalah versi yang kompatibel dengan 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;

Saya tidak berpikir ini adalah ide terbaik. Ini imageFlippedForRightToLeftLayoutDirection dimaksudkan untuk digunakan dengan arah tata letak terbalik - misalnya untuk negara-negara arab. Jadi menggunakan ini mungkin tidak selalu berfungsi seperti yang diinginkan.
Peter Stajger

1
Ya, Anda benar - dalam kasus saya itu persis untuk dukungan RTL. Kita semua tahu kode di SO adalah untuk referensi dan orang tidak benar-benar hanya menyalin / menempel tanpa memahaminya terlebih dahulu, bukan?
capikaw

1

Diuji di Swift 3 ke atas

Berikut adalah solusi sederhana untuk mengatasi masalah ini dengan ekstensi. Saya mengujinya dan berhasil. Anda bisa bercermin ke segala arah.

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

Penggunaan untuk kode ini

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

Jadi, Anda dapat menggunakan fungsi lain.


0

Inilah salah satu jawaban di atas yang dimodifikasi dan di Swift 3 yang menurut saya sangat berguna ketika Anda memiliki tombol yang perlu terus membalik gambar bolak-balik.

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)

    }

Menggunakan:

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

0

jawaban aroth di SWIFT 3:

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

0

Cepat 4

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

3
Jawaban hanya kode umumnya dianggap berkualitas rendah. Selain kode Anda, jelaskan bagaimana / mengapa ini bekerja, memperbaiki masalah, atau menjawab pertanyaan.
chharvey

1
Juga, ini tidak berfungsi untuk pertanyaan OP, karena dia meminta untuk membalik gambar. Kode di sini membalik tampilan gambar. Keduanya sangat berbeda dalam hal tempat penggunaannya. misalnya tombol mengambil gambar bukan tampilan gambar.
DS.

Juga, Anda baru saja menyalin jawaban saya dan menulis swift 4
Shaked Sayag

0

Karena pembongkaran lakukan hal berikut:

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

0

Anda dapat memutar gambar sesuai keinginan menggunakan ini

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

Solusi terbaik untuk memutar secara horizontal: Tonton video ini:

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

Atau gunakan kode ini:

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

}

Anda dapat menggunakan ui (tombol atau label atau tampilan atau gambar) apa pun dalam animasi ini.


1
Tidak disarankan untuk memposting link sebagai jawaban. Tautan bisa menjadi tidak valid suatu hari nanti. Jika Anda yakin metode ini bermanfaat, dapatkah Anda mempostingnya di sini?
Christopher
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.