iOS - UIImageView - jak obsłużyć orientację obrazu UIImage


80

Czy można skonfigurować UIImageViewobsługę orientacji obrazu? Kiedy ustawiam UIImageViewobraz z orientacją PRAWĄ (jest to zdjęcie z rolki aparatu), obraz jest obracany w prawo, ale chcę pokazać go w odpowiedniej orientacji, tak jak został zrobiony.

Wiem, że mogę obracać dane obrazu, ale czy można to zrobić bardziej elegancko?

Odpowiedzi:


142

Jeśli rozumiem, co chcesz zrobić, to zignorować orientację UIImage? Jeśli tak, możesz to zrobić:

UIImage *originalImage = [... whatever ...];

UIImage *imageToDisplay =
     [UIImage imageWithCGImage:[originalImage CGImage]
              scale:[originalImage scale]
              orientation: UIImageOrientationUp];

Więc tworzysz nowy UIImage z tymi samymi danymi pikseli co oryginał (do którego odwołuje się jego właściwość CGImage), ale określasz orientację, która nie obraca danych.


4
Swoją drogą, jak właściwie mogę obrócić dane obrazu?
Wang Liang

7
Wydaje mi się, że utworzyłbyś odpowiedni rozmiar CGContextwith CGBitmapContextCreate(lub ze UIGraphicsBeginImageContextskrótem), użyj CGContextRotateCTMdo ustawienia obrotu, użyj drawInRect:na UIImagelub CGContextDrawImagez właściwością obrazu CGImage, a następnie przekonwertuj kontekst na obraz za pomocą UIGraphicsGetImageFromCurrentImageContext(a następnie UIGraphicsEndImageContext), jeśli użył UIKit do stworzenia kontekstu lub CGBitmapContextCreateImagejeśli trzymałeś się Core Graphics. UIKit nie jest bardzo bezpieczny dla wątków, ale kod byłby schludniejszy.
Tommy

Nie mogę tego uruchomić, gdy umieszczam obraz w ImageView ... po prostu wyświetla obraz z jego oryginalną orientacją, mimo że tworzę obraz z lustrzanym odbiciem: [UIImage imageWithCGImage: image.CGImage scale: image .scale Orientation: UIImageOrientationUpMirrored] ... OP zapytał o użycie ImageView, ale nie mogę zmusić tego rozwiązania do pracy w ImageView ...
Ethan G

1
Działa dla PNG, ale nie dla HEIC.
DawnSong

50

Można całkowicie uniknąć ręcznego zmywania przekształca i skalowanie siebie, jak sugeruje an0 w tej odpowiedzi tutaj :

- (UIImage *)normalizedImage {
    if (self.imageOrientation == UIImageOrientationUp) return self; 

    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    [self drawInRect:(CGRect){0, 0, self.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

Dokumentacja dla metod UIImage size i drawInRect wyraźnie stwierdza, że ​​uwzględniają one orientację.


1
To ratuje życie.
Quark

gdzie mam to wkleić?
Frostmourne

25

Przekształciłem kod w odpowiedzi Anomie tutaj (skopiowany i wklejony powyżej przez suvish valsan) na Swift :

func fixOrientation() -> UIImage {
    if self.imageOrientation == UIImageOrientation.Up {
        return self
    }

    var transform = CGAffineTransformIdentity

    switch self.imageOrientation {
    case .Down, .DownMirrored:
        transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI));

    case .Left, .LeftMirrored:
        transform = CGAffineTransformTranslate(transform, self.size.width, 0);
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2));

    case .Right, .RightMirrored:
        transform = CGAffineTransformTranslate(transform, 0, self.size.height);
        transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2));

    case .Up, .UpMirrored:
        break
    }

    switch self.imageOrientation {

    case .UpMirrored, .DownMirrored:
        transform = CGAffineTransformTranslate(transform, self.size.width, 0)
        transform = CGAffineTransformScale(transform, -1, 1)

    case .LeftMirrored, .RightMirrored:
        transform = CGAffineTransformTranslate(transform, self.size.height, 0)
        transform = CGAffineTransformScale(transform, -1, 1);

    default:
        break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    let ctx = CGBitmapContextCreate(
        nil,
        Int(self.size.width),
        Int(self.size.height),
        CGImageGetBitsPerComponent(self.CGImage),
        0,
        CGImageGetColorSpace(self.CGImage),
        UInt32(CGImageGetBitmapInfo(self.CGImage).rawValue)
    )

    CGContextConcatCTM(ctx, transform);

    switch self.imageOrientation {
    case .Left, .LeftMirrored, .Right, .RightMirrored:
        // Grr...
        CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height,self.size.width), self.CGImage);

    default:
        CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width,self.size.height), self.CGImage);
        break;
    }

    // And now we just create a new UIImage from the drawing context
    let cgimg = CGBitmapContextCreateImage(ctx)

    let img = UIImage(CGImage: cgimg!)

    return img;
}

(Wymieniłem wszystkie occurencies parametru imagez self, ponieważ mój kod jest rozszerzeniem na UIImage).


EDYCJA: Wersja Swift 3.

Metoda zwraca wartość opcjonalną, ponieważ wiele wywołań pośrednich może się nie powieść, a ja nie lubię używać !.

func fixOrientation() -> UIImage? {

    guard let cgImage = self.cgImage else {
        return nil
    }

    if self.imageOrientation == UIImageOrientation.up {
        return self
    }

    let width  = self.size.width
    let height = self.size.height

    var transform = CGAffineTransform.identity

    switch self.imageOrientation {
    case .down, .downMirrored:
        transform = transform.translatedBy(x: width, y: height)
        transform = transform.rotated(by: CGFloat.pi)

    case .left, .leftMirrored:
        transform = transform.translatedBy(x: width, y: 0)
        transform = transform.rotated(by: 0.5*CGFloat.pi)

    case .right, .rightMirrored:
        transform = transform.translatedBy(x: 0, y: height)
        transform = transform.rotated(by: -0.5*CGFloat.pi)

    case .up, .upMirrored:
        break
    }

    switch self.imageOrientation {
    case .upMirrored, .downMirrored:
        transform = transform.translatedBy(x: width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)

    case .leftMirrored, .rightMirrored:
        transform = transform.translatedBy(x: height, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)

    default:
        break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    guard let colorSpace = cgImage.colorSpace else {
        return nil
    }

    guard let context = CGContext(
        data: nil,
        width: Int(width),
        height: Int(height),
        bitsPerComponent: cgImage.bitsPerComponent,
        bytesPerRow: 0,
        space: colorSpace,
        bitmapInfo: UInt32(cgImage.bitmapInfo.rawValue)
        ) else {
            return nil
    }

    context.concatenate(transform);

    switch self.imageOrientation {

    case .left, .leftMirrored, .right, .rightMirrored:
        // Grr...
        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: height, height: width))

    default:
        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
    }

    // And now we just create a new UIImage from the drawing context
    guard let newCGImg = context.makeImage() else {
        return nil
    }

    let img = UIImage(cgImage: newCGImg)

    return img;
}

(Uwaga: odes wersji Swift 3 kompiluje się pod Xcode 8.1, ale nie przetestowano tego, że faktycznie działa. Może gdzieś być literówka, pomieszana szerokość / wysokość itp. Możesz wskazać / naprawić wszelkie błędy).


Użyłem powyższego kodu po konwersji na Swift 3. Sprawdź moją odpowiedź poniżej, jeśli ktoś potrzebuje wersji Swift 3
Waseem05

Orientacja obrazu w ogóle się nie zmieniła. Przepraszamy, jestem nowy w programowaniu na iOS. Co zrobiłem, to użyłem funkcji do rozszerzenia UIImage, a następnie ustawiłem ją programowo w środku func viewDidLoad. To zdjęcie pochodzi z telefonu samsung photos.google.com/share/ i ma dane exif o orientacji 270 CW. Oto jak go używamlet background: UIImage? = UIImage(named: "background_image")?.fixOrientation() backgroundImage.image = background
HendraWD

Czy ktoś ma problemy z wyciekiem pamięci przy użyciu tego @Nicolas? wygląda na to, że CGImages nie jest zwalniany. Moja aplikacja jest aplikacją do masowego zarządzania zdjęciami i obsługuje wiele zdjęć. Ta funkcja wydaje się przeciekać pamięć za każdym razem, gdy jest uruchamiana. Czy są jakieś szybkie rozwiązania tego problemu?
Michael Reilly,

@MichaelReilly Hmm, nie przyjrzałem się temu szczegółowo, ale wywołania CoreGraphics powinny działać szybko z ARC.
Nicolas Miari

@MichaelReilly Znalazłem tę odpowiedź, która wydaje się potwierdzać moją obserwację: stackoverflow.com/a/25790214/433373
Nicolas Miari

24

Ta metoda najpierw sprawdza aktualną orientację UIImage, a następnie zmienia orientację zgodnie z ruchem wskazówek zegara i zwraca UIImage. Możesz pokazać ten obraz jako

self.imageView.image = rotateImage (currentUIImage)

   func rotateImage(image:UIImage)->UIImage
    {
        var rotatedImage = UIImage();
        switch image.imageOrientation
        {
            case UIImageOrientation.Right:
            rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Down);

           case UIImageOrientation.Down:
            rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Left);

            case UIImageOrientation.Left:
            rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Up);

             default:
            rotatedImage = UIImage(CGImage:image.CGImage!, scale: 1, orientation:UIImageOrientation.Right);
        }
        return rotatedImage;
    }

Wersja Swift 4

func rotateImage(image:UIImage) -> UIImage
    {
        var rotatedImage = UIImage()
        switch image.imageOrientation
        {
        case .right:
            rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .down)

        case .down:
            rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .left)

        case .left:
            rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .up)

        default:
            rotatedImage = UIImage(cgImage: image.cgImage!, scale: 1.0, orientation: .right)
        }

        return rotatedImage
    }

Cześć Varender i dzięki za pomoc w SO. Czy mógłbyś trochę rozwinąć, jak myślisz, że może to pomóc Martinowi? Jak bardziej eleganckie jest Twoje rozwiązanie niż obracanie danych?
J. Chomel

1. weźmiemy aktualny UIImage z UIImageView 2. wywołamy tę metodę (rotateImage) i przekażemy ten aktualny UIImage jako argument 3. zapisanie zwróconej wartości do UIImageView.image / * spowoduje to obrócenie danych w widoku obrazu: ) :)
varender singh

proszę pana, według mnie to najlepsza odpowiedź, ponieważ jeśli obrócimy cały UIImageView, to UIImageView X będzie wartością ujemną. Ale jeśli obrócimy dane, UIImageView pozostanie na miejscu i tylko dane zostaną obrócone.Jeśli weźmiesz kwadratowy UIImageView, możesz po prostu przekształcić cały UIImageView za pomocą CGAffineTransformMakeRotate.
varender singh

To powinna być akceptowana odpowiedź! Zadziałało jak urok :)
Ely Dantas

in swift 3: rotatedImage = UIImage (cgImage: image.cgImage !, scale: 1, orientacja: UIImageOrientation.right)
Ansal Antony

19

Swift 3.1

func fixImageOrientation(_ image: UIImage)->UIImage {
    UIGraphicsBeginImageContext(image.size)
    image.draw(at: .zero)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage ?? image
}

To idealne rozwiązanie :)
miff

zasługujesz na wszystkie bity, mój przyjacielu
Mitchell Gant

To jest lepsze niż to . Działa to w Swift 4, ale tak nie jest.
AechoLiu

Dzięki. Ten działa, jeśli chcesz przesłać obraz na serwer, a nie tylko wyświetlać go jako większość innych odpowiedzi.
Nomad Developer,

działa świetnie. Robi dowolne zdjęcie i zapisuje je z orientacją
.up

9

Rozszerzenie UIImage w Swift. Tak naprawdę wcale nie musisz robić tego całego przewracania. Oryginał Objective-C jest tutaj , ale dodałem bit, który szanuje alfa oryginalnego obrazu (prymitywnie, ale działa, aby odróżnić nieprzezroczyste obrazy od przezroczystych).

// from https://github.com/mbcharbonneau/UIImage-Categories/blob/master/UIImage%2BAlpha.m
// Returns true if the image has an alpha layer
    private func hasAlpha() -> Bool {
        guard let cg = self.cgImage else { return false }
        let alpha = cg.alphaInfo
        let retVal = (alpha == .first || alpha == .last || alpha == .premultipliedFirst || alpha == .premultipliedLast)
        return retVal
    }

    func normalizedImage() -> UIImage? {
        if self.imageOrientation == .up {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(self.size, !self.hasAlpha(), self.scale)
        var rect = CGRect.zero
        rect.size = self.size
        self.draw(in: rect)
        let retVal = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return retVal
    }

8

tutaj jest praktyczny przykładowy kod, biorąc pod uwagę orientację obrazu:

#define rad(angle) ((angle) / 180.0 * M_PI)
- (CGAffineTransform)orientationTransformedRectOfImage:(UIImage *)img
{
    CGAffineTransform rectTransform;
    switch (img.imageOrientation)
    {
        case UIImageOrientationLeft:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -img.size.height);
            break;
        case UIImageOrientationRight:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -img.size.width, 0);
            break;
        case UIImageOrientationDown:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -img.size.width, -img.size.height);
            break;
        default:
            rectTransform = CGAffineTransformIdentity;
    };

    return CGAffineTransformScale(rectTransform, img.scale, img.scale);
}


- (UIImage *)croppedImage:(UIImage*)orignialImage InRect:(CGRect)visibleRect{
    //transform visible rect to image orientation
    CGAffineTransform rectTransform = [self orientationTransformedRectOfImage:orignialImage];
    visibleRect = CGRectApplyAffineTransform(visibleRect, rectTransform);

    //crop image
    CGImageRef imageRef = CGImageCreateWithImageInRect([orignialImage CGImage], visibleRect);
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:orignialImage.scale orientation:orignialImage.imageOrientation];
    CGImageRelease(imageRef);
    return result;
}

8

Przekonwertowałem kod z odpowiedzi @Nicolas Miari na Swift 3 na wypadek, gdyby ktoś tego potrzebował

func fixOrientation() -> UIImage
{

    if self.imageOrientation == UIImageOrientation.up {
        return self
    }

    var transform = CGAffineTransform.identity

    switch self.imageOrientation {
    case .down, .downMirrored:
        transform = transform.translatedBy(x: self.size.width, y: self.size.height)
        transform = transform.rotated(by: CGFloat(M_PI));

    case .left, .leftMirrored:
        transform = transform.translatedBy(x: self.size.width, y: 0);
        transform = transform.rotated(by: CGFloat(M_PI_2));

    case .right, .rightMirrored:
        transform = transform.translatedBy(x: 0, y: self.size.height);
        transform = transform.rotated(by: CGFloat(-M_PI_2));

    case .up, .upMirrored:
        break
    }


    switch self.imageOrientation {

    case .upMirrored, .downMirrored:
        transform = transform.translatedBy(x: self.size.width, y: 0)
        transform = transform.scaledBy(x: -1, y: 1)

    case .leftMirrored, .rightMirrored:
        transform = transform.translatedBy(x: self.size.height, y: 0)
        transform = transform.scaledBy(x: -1, y: 1);

    default:
        break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    let ctx = CGContext(
        data: nil,
        width: Int(self.size.width),
        height: Int(self.size.height),
        bitsPerComponent: self.cgImage!.bitsPerComponent,
        bytesPerRow: 0,
        space: self.cgImage!.colorSpace!,
        bitmapInfo: UInt32(self.cgImage!.bitmapInfo.rawValue)
    )



    ctx!.concatenate(transform);

    switch self.imageOrientation {

    case .left, .leftMirrored, .right, .rightMirrored:
        // Grr...
        ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.height ,height:self.size.width))

    default:
        ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.width ,height:self.size.height))
        break;
    }

    // And now we just create a new UIImage from the drawing context
    let cgimg = ctx!.makeImage()

    let img = UIImage(cgImage: cgimg!)

    return img;

}

Po przechwyceniu obrazu w metodach delegata imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any] let imageCaptured:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage obraz jest zawsze właściwyOrientation i ta metoda zwraca obraz :(
Sumeet Mourya

Tak, orientacja obrazu jest w porządku. W porządku, ale wyświetla się poprawnie na UIImageView. Apple ma pewne dane wewnętrzne, które są tutaj używane do
poprawnego

4

Dziękuję Waseem05 za tłumaczenie Swift 3, ale jego metoda zadziałała dla mnie tylko wtedy, gdy zawinąłem ją do rozszerzenia do UIImage i umieściłem ją na zewnątrz / poniżej klasy nadrzędnej w następujący sposób:

extension UIImage {

        func fixOrientation() -> UIImage
        {

            if self.imageOrientation == UIImageOrientation.up {
            return self
        }

        var transform = CGAffineTransform.identity

        switch self.imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: CGFloat(M_PI));

        case .left, .leftMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0);
            transform = transform.rotated(by: CGFloat(M_PI_2));

        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: self.size.height);
            transform = transform.rotated(by: CGFloat(-M_PI_2));

        case .up, .upMirrored:
            break
        }


        switch self.imageOrientation {

        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)

        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: self.size.height, y: 0)
            transform = transform.scaledBy(x: -1, y: 1);

        default:
            break;
        }

        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        let ctx = CGContext(
            data: nil,
            width: Int(self.size.width),
            height: Int(self.size.height),
            bitsPerComponent: self.cgImage!.bitsPerComponent,
            bytesPerRow: 0,
            space: self.cgImage!.colorSpace!,
            bitmapInfo: UInt32(self.cgImage!.bitmapInfo.rawValue)
        )



        ctx!.concatenate(transform);

        switch self.imageOrientation {

        case .left, .leftMirrored, .right, .rightMirrored:
            // Grr...
            ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.height ,height:self.size.width))

        default:
            ctx?.draw(self.cgImage!, in: CGRect(x:0 ,y: 0 ,width: self.size.width ,height:self.size.height))
            break;
        }

        // And now we just create a new UIImage from the drawing context
        let cgimg = ctx!.makeImage()

        let img = UIImage(cgImage: cgimg!)

        return img;

    }
}

Następnie nazwał to z:

let correctedImage:UIImage = wonkyImage.fixOrientation()

I wszystko było wtedy dobrze! Apple powinno ułatwić odrzucanie orientacji, gdy nie potrzebujemy przedniej / tylnej kamery i metadanych dotyczących orientacji urządzenia w górę / w dół / w lewo / w prawo.


4

Jeśli potrzebujesz obrócić i naprawić orientację obrazu poniżej rozszerzenie byłoby przydatne.

extension UIImage {

    public func imageRotatedByDegrees(degrees: CGFloat) -> UIImage {
        //Calculate the size of the rotated view's containing box for our drawing space
        let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi / 180)
        rotatedViewBox.transform = t
        let rotatedSize: CGSize = rotatedViewBox.frame.size
        //Create the bitmap context
        UIGraphicsBeginImageContext(rotatedSize)
        let bitmap: CGContext = UIGraphicsGetCurrentContext()!
        //Move the origin to the middle of the image so we will rotate and scale around the center.
        bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
        //Rotate the image context
        bitmap.rotate(by: (degrees * CGFloat.pi / 180))
        //Now, draw the rotated/scaled image into the context
        bitmap.scaleBy(x: 1.0, y: -1.0)
        bitmap.draw(self.cgImage!, in: CGRect(x: -self.size.width / 2, y: -self.size.height / 2, width: self.size.width, height: self.size.height))
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }


    public func fixedOrientation() -> UIImage {
        if imageOrientation == UIImageOrientation.up {
            return self
        }

        var transform: CGAffineTransform = CGAffineTransform.identity

        switch imageOrientation {
        case UIImageOrientation.down, UIImageOrientation.downMirrored:
            transform = transform.translatedBy(x: size.width, y: size.height)
            transform = transform.rotated(by: CGFloat.pi)
            break
        case UIImageOrientation.left, UIImageOrientation.leftMirrored:
            transform = transform.translatedBy(x: size.width, y: 0)
            transform = transform.rotated(by: CGFloat.pi/2)
            break
        case UIImageOrientation.right, UIImageOrientation.rightMirrored:
            transform = transform.translatedBy(x: 0, y: size.height)
            transform = transform.rotated(by: -CGFloat.pi/2)
            break
        case UIImageOrientation.up, UIImageOrientation.upMirrored:
            break
        }

        switch imageOrientation {
        case UIImageOrientation.upMirrored, UIImageOrientation.downMirrored:
            transform.translatedBy(x: size.width, y: 0)
            transform.scaledBy(x: -1, y: 1)
            break
        case UIImageOrientation.leftMirrored, UIImageOrientation.rightMirrored:
            transform.translatedBy(x: size.height, y: 0)
            transform.scaledBy(x: -1, y: 1)
        case UIImageOrientation.up, UIImageOrientation.down, UIImageOrientation.left, UIImageOrientation.right:
            break
        }

        let ctx: CGContext = CGContext(data: nil,
                                       width: Int(size.width),
                                       height: Int(size.height),
                                       bitsPerComponent: self.cgImage!.bitsPerComponent,
                                       bytesPerRow: 0,
                                       space: self.cgImage!.colorSpace!,
                                       bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!

        ctx.concatenate(transform)

        switch imageOrientation {
        case UIImageOrientation.left, UIImageOrientation.leftMirrored, UIImageOrientation.right, UIImageOrientation.rightMirrored:
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
        default:
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            break
        }

        let cgImage: CGImage = ctx.makeImage()!

        return UIImage(cgImage: cgImage)
    }
}

2
extension UIImage {
    func fixImageOrientation() -> UIImage {
        UIGraphicsBeginImageContext(self.size)
        self.draw(at: .zero)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage ?? self
    }
}
  1. Utwórz rozszerzenie jak najlepszy przykład.
  2. Nazwij to: imageView.image?.fixImageOrientation()lubUIImage(named: "someImage").fixImageOrientation()

  3. Powodzenia wszystkim!


To działa dobrze. Ale pamięć gromadzi się jak cokolwiek, a aplikacja ulega awarii, jeśli wywoływana jest pętla.
abhimuralidharan

@abhimuralidharan, nie sprawdziłem tego w pętli, ale w 100% istnieje sposób na zastosowanie.
Mihail Salari

1

Swift 3.0 wersja odpowiedzi Tommy'ego

let imageToDisplay = UIImage.init(cgImage: originalImage.cgImage!, scale: originalImage.scale, orientation: UIImageOrientation.up)

0

Zainspirowany @Aqua Answer .....

w celu C

- (UIImage *)fixImageOrientation:(UIImage *)img {

   UIGraphicsBeginImageContext(img.size);
   [img drawAtPoint:CGPointZero];

   UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();

   if (newImg) {
       return newImg;
   }

   return img;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.