UIImage yatay olarak nasıl çevrilir?


111

UIImageYatay olarak nasıl çevirilir, sınıf referansında UIImageOrientationUpMirrorednumaralandırma değeri buldum UIImage, bu özelliği çevirmek için nasıl kullanacağım UIImage.


Aroth'un iyi cevabına eklemek için, Apple bu bağlantıda
coco

Kabul edilenler benim için çalışmadığı için bu kategoriyi buldum . Tıkır tıkır çalışıyor.
dwbrito

Yanıtlar:


238

Objective-C

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

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

hızlı

let flippedImage = myImage.withHorizontallyFlippedOrientation()

14
Bu yanıtla ilgili iki sorun var - ölçek, retinayla uyumlu görüntülerde 1.0 değil ve bazı nedenlerden dolayı tersine çevirmediğinde UIImageOrientationUpçalıştı UIImageOrientationUpMirrored. Bu işe yaradı -image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp]
Kof

1
@Kof, fark ettiğim gibi, ilettiğiniz oryantasyon parametresi, "bu resmi bana bu belirli oryantasyonla ver" yerine "sourceImage'ın yönünün zaten ne olduğunu" belirlemek için kullanılıyor. Böylece sourceImage.imageOrientation parametresini inceleyebilir ve size istediğinizi vermesi için yöntemi kandırmak için farklı bir yönelimde geçebilirsiniz
Ege Akpinar

6
sourceImage.scaleÖlçek için kullanmak daha iyi olur .
Sam Soffes

Bunu Swift'de nasıl yapabilirim? [UIImage imageWithCGImage ...] burada kullanılamaz.
Lim Thye Chean

3
Bunu yapmaya çalıştığımda tamamen kırılmış gibi görünüyor [flippedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]. Herhangi bir fikrin neden?
devios1

70

Bunu başarmanın çok basit bir yolu, UIImage yerine UIImageView oluşturmak ve UIImageView üzerinde dönüşümü yapmaktır.

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

Bu yardımcı olur umarım.


2
Bu, benim için işleme moduyla UIImagebirleştirildiğinde yan etkileri olduğunu bulduğum manipülasyondan çok daha iyi sonuç verdi UIImageRenderingModeAlwaysTemplate.
devios1

2
Bunu paylaştığın için teşekkürler Bu gönderiyle ilişkili bu bulmacanın "cevabını" alma konusunda hiç şansım olmadı, ancak cevabınız olağanüstü derecede iyi çalıştı ve sadece 1 satır koddu.
Adrian

Harika çalışıyor! iOS 9+ artık flipsForRightToLeftLayoutDirection'ı da içeriyor, ancak henüz iOS 8+ uygulamaları için çalışmayacak.

3
yourImageView.transform = CGAffineTransformIdentity
Çevirmeyi

UIImageView'da bu yöntemin 'dönüştürdüğüne' dikkat edin. Gerçek UIImage'ı çevirmez.
Yavaş

36

OpenGL dokusunu kullanarak başlatmak için genellikle dikey çevirme gereklidir glTexImage2d(...). Yukarıda önerilen hileler aslında görüntü verilerini değiştirmez ve bu durumda çalışmayacaktır. İşte, https://stackoverflow.com/a/17909372'den esinlenerek gerçek veri çevirmeyi yapmak için bir kod.

- (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
Bu nasıl görüntüyü çevirir? Görüntüyü yeniden çiziyor gibi görünüyor.
Jonathan.

@Jonathan. Çizim sırasında farklı koordinat sistemleri (yani Y ekseni yönü) nedeniyle döndüğünü düşünüyorum.
Alexey Podlasov

Görüntüyü dikey olarak çevirmek için bunu kullanmanın bir yolu var mı?
Praxiteles

bu yöntem aynı zamanda görüntü oluşturmayı da güzel bir şekilde destekler - her zaman şablon
Peter Stajger

3
Kalite sorununu düzeltmek için UIGraphicsBeginImageContextWithOptions (image.size, NO, image.scale) kullanın; yerine.
Nick Lockwood

14

İmageFlippedForRightToLeftLayoutDirection ile denedim ve farklı yönlere sahip yeni bir UIImage oluşturmayı denedim, ancak en azından bu, resmimi çevirmek için bulduğum tek çözüm

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

Benim oyun alanımda gördüğünüz gibi işe yaradı !! :) görüntü açıklamasını buraya girin

Ve tabii ki finalImage = UIImage (CIImage: rotada3)


Maalesef bu artık çalışmıyor gibi görünüyor, en azından kamerayla çekilen fotoğraflarla ...
Oni_01

12

Görüntü Yönünün Tanımladığı Gibi:

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

AVCaptureSession'dan UIImage kullanımı gibi daha fazla koşul için bazı iyileştirmeler yaptım.

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

işte hızlı versiyon: (Bu soruyu yorumlarda gördüm)

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

Bu, bir UIImage'ı yatay olarak yansıtmak / çevirmek için sağlam bir uygulamadır ve görüntüye ileri geri uygulanabilir. Alttaki görüntü verilerini değiştirdiği için çizim (ekran görüntüsü gibi) da değişecektir. Çalışmak için test edildi, kalite kaybı yok.

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

Bu bazıları için faydalı olabilir:

    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

Swift 3/4 için:

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

Bu UIImageView için, OP bir UIImage arıyor olan
Shizam

2

Basit bir uzantı.

extension UIImage {

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

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

Kullanımı:

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

Uzantılar, Swift'in en iyi özelliklerinden biridir. Yukarıdaki orijinal yanıtların bunu tavsiye etmemesine şaşırdım. Bu sürümü çok daha iyi seviyorum.
DS.

1

Bu, çalışan bir iOS8 / 9 uyumlu sürümdür:

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;

Bunun en iyi fikir olduğunu sanmıyorum. Bu imageFlippedForRightToLeftLayoutDirection , örneğin Arap ülkeleri için ters çevrilmiş yerleşim yönleriyle kullanılmak üzere tasarlanmıştır. Bu nedenle, bunu kullanmak her zaman istendiği gibi çalışmayabilir.
Peter Stajger

1
Evet, haklısınız - benim durumumda tam olarak RTL desteği içindi. SO'daki kodun referans amaçlı olduğunu hepimiz biliyoruz ve insanlar gerçekten anlamadan kopyalayıp yapıştırmazlar, değil mi?
capikaw

1

Swift 3 ve üzerinde test edildi

Uzantılarla bu sorunu çözmenin basit çözümü burada. Test ettim ve işe yaradı. Herhangi bir yönde aynalayabilirsiniz.

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

Bu kodun kullanımı

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

Yani diğer işlevleri de kullanabilirsiniz.


0

İşte yukarıdaki cevaplardan biri değiştirilmiş ve Swift 3'te , görüntüyü ileri geri çevirmeye devam etmeniz gereken bir düğmeniz olduğunda özellikle yararlı bulduğum.

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)

    }

kullanın:

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

0

aroth'un SWIFT 3'teki cevabı :

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
Yalnızca kod yanıtları genellikle düşük kaliteli olarak kabul edilir. Kodunuza ek olarak, nasıl / neden çalıştığını, sorunu giderdiğini veya soruyu yanıtladığını açıklayın.
chharvey

1
Ayrıca, görüntüyü çevirmek istediğinden, bu OPs sorusu için çalışmaz. Buradaki kod, görüntü görünümünü ters çevirir. Her ikisi de nerede kullanılabilecekleri açısından çok farklıdır. örneğin bir düğme bir görüntüyü değil bir görüntüyü alır.
DS.

Ayrıca, cevabımı kopyaladınız ve hızlı 4
Shaked Sayag

0

Paketin açılmaması nedeniyle aşağıdakileri yapın:

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

0

bunu kullanarak resmi istediğiniz gibi döndürebilirsiniz

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

Yatay olarak döndürmek için en iyi çözüm: Bu videoyu izleyin:

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

Veya bu kodu kullanın:

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

}

Bu animasyonda herhangi bir kullanıcı arayüzünü (düğme veya etiket veya uiview veya resim) kullanabilirsiniz.


1
Cevap olarak bir bağlantı gönderilmesi tavsiye edilmez. Bağlantı bir gün geçersiz hale gelebilir. Yöntemin yararlı olduğuna inanıyorsanız, lütfen buraya gönderebilir misiniz?
Christopher
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.