Làm thế nào để lật UIImage theo chiều ngang?


111

Làm thế nào để lật UIImagetheo chiều ngang, tôi tìm thấy UIImageOrientationUpMirroredgiá trị liệt kê trong UIImagetham chiếu lớp, cách sử dụng thuộc tính này để lật UIImage.


Để thêm vào câu trả lời hay ho của aroth, Apple giải thích rất rõ các loại định hướng hình ảnh khác tại liên kết này
coco

Vì mục được chấp nhận không hoạt động với tôi, tôi đã tìm thấy danh mục này . Hoạt động như một sự quyến rũ.
dwbrito 13/1213

Câu trả lời:


237

Objective-C

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

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

Nhanh

let flippedImage = myImage.withHorizontallyFlippedOrientation()

14
Có hai vấn đề với câu trả lời này - tỷ lệ không phải là 1,0 ở hình ảnh cạnh tranh võng mạc và vì một số lý do UIImageOrientationUpđã hoạt động trong khi UIImageOrientationUpMirroredkhông lật nó. Điều này đã hoạt động -image = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationUp]
Kof

1
@Kof như tôi nhận thấy, tham số định hướng mà bạn truyền vào được sử dụng để xác định 'định hướng của sourceImage đã là gì' thay vì 'cung cấp cho tôi hình ảnh này với hướng cụ thể này'. Do đó, bạn có thể kiểm tra thông số sourceImage.imageOrientation và vượt qua trong một định hướng khác nhau để đánh lừa phương pháp này để cung cấp cho bạn những gì bạn muốn
Ege Akpinar

6
Sẽ tốt hơn nếu sử dụng sourceImage.scalecho cân.
Sam Soffes

Làm thế nào để làm điều này trong Swift? [UIImage imageWithCGImage ...] không khả dụng ở đó.
Lim Thye Chean

3
Điều này dường như hoàn toàn phá vỡ khi tôi cố gắng làm [flippedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]. Bất kỳ ý tưởng tại sao?
devos1

70

Một cách rất đơn giản mà bạn có thể đạt được là tạo UIImageView thay vì UIImage và thực hiện chuyển đổi trên UIImageView.

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

Hi vọng điêu nay co ich.


2
Điều này kết thúc với tôi hiệu quả hơn nhiều so với UIImagethao tác, mà tôi thấy có tác dụng phụ khi kết hợp với UIImageRenderingModeAlwaysTemplatechế độ kết xuất.
defos1

2
Cảm ơn vì đã chia sẻ. Tôi đã không gặp may với "câu trả lời" cho câu đố liên quan đến bài đăng này, nhưng câu trả lời của bạn hoạt động tốt một cách phi thường và chỉ có 1 dòng mã.
Adrian

Hoạt động tuyệt vời! iOS 9+ hiện cũng bao gồm flipsForRightToLeftLayoutDirection, nhưng nó sẽ không hoạt động cho các ứng dụng iOS 8+.

3
Nếu bạn muốn thiết lập lại lật, sau đó sử dụngyourImageView.transform = CGAffineTransformIdentity
chanil

Lưu ý rằng phương pháp này 'biến đổi' trên UIImageView. Nó không lật UIImage thực tế.
chậm

36

Lật dọc thường được yêu cầu để khởi tạo kết cấu OpenGL bằng cách sử dụng glTexImage2d(...). Các thủ thuật được đề xuất ở trên thực tế không sửa đổi dữ liệu hình ảnh và sẽ không hoạt động trong trường hợp này. Đây là mã để thực hiện việc lật dữ liệu thực tế được lấy cảm hứng từ 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
Làm thế nào để lật hình ảnh này? Nó chỉ giống như nó vẽ lại hình ảnh.
Jonathan.

@Jonathan. Tôi nghĩ rằng nó bị lật do các hệ tọa độ khác nhau (tức là hướng trục Y) trong khi vẽ.
Alexey Podlasov

Có cách nào sử dụng điều này để lật hình ảnh theo chiều dọc không?
Praxiteles

phương pháp này độc đáo cũng hỗ trợ dựng hình ảnh - luôn mẫu
Peter Stajger

3
Để khắc phục sự cố chất lượng, hãy sử dụng UIGraphicsBeginImageContextWithOptions (image.size, NO, image.scale); thay thế.
Nick Lockwood

14

Tôi đã thử với imageFlippedForRightToLeftLayoutDirection và tạo UIImage mới với các hướng khác nhau nhưng ít nhất đây là giải pháp duy nhất tôi tìm thấy để lật hình ảnh của mình

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

Như bạn có thể thấy trong sân chơi của tôi, nó đã hoạt động !! :) nhập mô tả hình ảnh ở đây

Và tất nhiên, hãy để finalImage = UIImage (CIImage: rotada3)


Xin lỗi nhưng có vẻ này thích không làm việc nữa, ít nhất là với hình ảnh camera chụp ...
Oni_01

12

Vì nó Định hướng Hình ảnh xác định:

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

Tôi đã thực hiện một số cải tiến cho nhiều trường hợp hơn như xử lý UIImage từ 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

đây là phiên bản nhanh: (Tôi đã thấy câu hỏi này trong nhận xét)

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

Đây là một triển khai chắc chắn để phản chiếu / lật UIImage theo chiều ngang và có thể áp dụng cho hình ảnh qua lại. Vì nó thay đổi dữ liệu hình ảnh bên dưới, bản vẽ (như, ảnh chụp màn hình) cũng sẽ thay đổi. Đã kiểm tra để làm việc, không giảm chất lượng.

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

Có thể điều này sẽ được sử dụng cho một số:

    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

Đối với Swift 3/4:

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

Đây là một UIImageView, OP đang tìm kiếm một UIImage
Shizam

2

Một phần mở rộng đơn giản.

extension UIImage {

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

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

Sử dụng:

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

Tiện ích mở rộng là một trong những tính năng tốt nhất của Swift. Tôi rất ngạc nhiên khi các câu trả lời ban đầu ở trên không đề xuất được điều đó. Tôi thích phiên bản này hơn rất nhiều.
DS.

1

Đây là phiên bản tương thích iOS8 / 9 đang hoạt động:

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;

Tôi không nghĩ rằng đây là ý tưởng tốt nhất. Điều này imageFlippedForRightToLeftLayoutDirection có nghĩa là được sử dụng với các hướng bố cục lật - ví dụ cho các quốc gia Ả Rập. Vì vậy, sử dụng điều này có thể không phải lúc nào cũng hoạt động như mong muốn.
Peter Stajger

1
Vâng, bạn chính xác - trong trường hợp của tôi, nó chính xác dành cho hỗ trợ RTL. Tất cả chúng ta đều biết mã trên SO là để tham khảo và mọi người không thực sự chỉ sao chép / dán mà không hiểu nó trước, phải không?
capikaw

1

Đã thử nghiệm trong Swift 3 trở lên

Đây là giải pháp đơn giản để đạt được vấn đề này với các tiện ích mở rộng. Tôi thử nghiệm nó và nó hoạt động. Bạn có thể phản chiếu theo bất kỳ hướng nào.

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

Cách sử dụng cho mã này

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

Vì vậy, bạn có thể sử dụng các chức năng khác.


0

Đây là một trong những câu trả lời ở trên đã được sửa đổi và trong Swift 3 mà tôi thấy đặc biệt hữu ích khi bạn có một nút cần liên tục lật qua lại hình ảnh.

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)

    }

Sử dụng:

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

0

câu trả lời của aroth trong 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
Các câu trả lời chỉ có mã thường được coi là chất lượng thấp. Ngoài mã của bạn, hãy giải thích cách / tại sao nó hoạt động, khắc phục sự cố hoặc trả lời câu hỏi.
chharvey

1
Ngoài ra, điều này không hiệu quả đối với câu hỏi OP, vì anh ta đang yêu cầu lật hình ảnh. Mã ở đây lật chế độ xem hình ảnh. Cả hai đều rất khác nhau về nơi chúng có thể được sử dụng. ví dụ: một nút lấy một hình ảnh không phải là một chế độ xem hình ảnh.
DS.

Ngoài ra, bạn chỉ cần sao chép câu trả lời của tôi và viết nhanh 4
Shaked Sayag

0

Do việc mở gói, hãy làm như sau:

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

0

bạn có thể xoay hình ảnh như bạn muốn bằng cách sử dụng

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

Giải pháp tốt nhất để xoay theo chiều ngang: Xem video này:

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

Hoặc sử dụng mã này:

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

}

Bạn có thể sử dụng bất kỳ ui nào (nút hoặc nhãn hoặc uiview hoặc hình ảnh) trong hoạt ảnh này.


1
Nó không được khuyến khích để đăng một liên kết như một câu trả lời. Liên kết có thể trở nên không hợp lệ vào một ngày nào đó. Nếu bạn tin rằng phương pháp này hữu ích, bạn có thể vui lòng đăng nó ở đây không?
Christopher
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.