iOS - UIImageView - cách xử lý hướng hình ảnh UIImage


80

Có thể thiết lập UIImageViewđể xử lý hướng hình ảnh không? Khi tôi đặt UIImageViewảnh thành hình ảnh có hướng RIGHT (đó là ảnh từ thư viện ảnh), hình ảnh được xoay sang phải, nhưng tôi muốn hiển thị nó theo hướng thích hợp, như khi nó được chụp.

Tôi biết tôi có thể xoay dữ liệu hình ảnh nhưng có thể làm điều đó thanh lịch hơn không?

Câu trả lời:


142

Nếu tôi hiểu, điều bạn muốn làm là bỏ qua định hướng của UIImage? Nếu vậy thì bạn có thể làm điều này:

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

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

Vì vậy, bạn đang tạo một UIImage mới với dữ liệu pixel giống như bản gốc (được tham chiếu qua thuộc tính CGImage) nhưng bạn đang chỉ định một hướng không xoay dữ liệu.


4
Nhân tiện, tôi thực sự có thể xoay dữ liệu hình ảnh bằng cách nào?
Wang Liang

7
Tôi đoán bạn sẽ tạo kích thước phù hợp CGContextvới CGBitmapContextCreate(hoặc bằng tốc UIGraphicsBeginImageContextký), sử dụng CGContextRotateCTMđể đặt xoay, sử dụng drawInRect:trên UIImagehoặc CGContextDrawImagevới thuộc tính của hình ảnh CGImage, sau đó chuyển đổi ngữ cảnh thành hình ảnh với UIGraphicsGetImageFromCurrentImageContext(và, sau đó, UIGraphicsEndImageContext) nếu bạn đã sử dụng UIKit để tạo bối cảnh hoặc CGBitmapContextCreateImagenếu bạn đang gắn bó với Đồ họa cốt lõi. UIKit không an toàn cho chuỗi, nhưng mã sẽ gọn gàng hơn.
Tommy

Tôi không thể làm cho điều này hoạt động khi tôi đặt hình ảnh trong ImageView ... nó chỉ hiển thị hình ảnh với hướng ban đầu mặc dù tôi đang tạo hình ảnh với hướng phản chiếu: [UIImage imageWithCGImage: image.CGImage scale: image định hướng .scale: UIImageOrientationUpMirrored] ... OP hỏi về việc sử dụng ImageView nhưng tôi không thể có được giải pháp này để làm việc trong một ImageView ...
Ethan G

1
Tuy nhiên, hoạt động cho PNG, không cho HEIC.
DawnSong

50

Bạn hoàn toàn có thể tránh tự mình thực hiện các chuyển đổi và mở rộng quy mô theo cách thủ công, như được đề xuất bởi an0 trong câu trả lời này ở đây :

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

Tài liệu về kích thước các phương thức UIImage và drawInRect tuyên bố rõ ràng rằng chúng có tính đến hướng.


1
Đây là một tiết kiệm cuộc sống.
Quark

Tôi dán cái này ở đâu?
Frostmourne

25

Tôi đã chuyển đổi mã trong câu trả lời của Anomie tại đây (được suvish valsan sao chép ở trên) thành 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;
}

(Tôi đã thay thế tất cả các vị trí xuất hiện của tham số imagebằng self, bởi vì mã của tôi là một phần mở rộng đang bật UIImage).


CHỈNH SỬA: Phiên bản Swift 3.

Phương thức trả về một tùy chọn, vì nhiều lệnh gọi trung gian có thể không thành công và tôi không thích sử dụng !.

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

(Lưu ý: Phiên bản Swift 3 được biên dịch theo Xcode 8.1, nhưng chưa kiểm tra nó thực sự hoạt động. Có thể có lỗi đánh máy ở đâu đó, nhầm lẫn chiều rộng / chiều cao, v.v. Vui lòng chỉ / sửa bất kỳ lỗi nào).


Tôi đã sử dụng trên mã sau khi chuyển đổi để nhanh chóng 3.Check câu trả lời của tôi dưới đây nếu ai cần nhanh chóng 3 phiên bản
Waseem05

Hướng hình ảnh hoàn toàn không thay đổi. Xin lỗi, tôi là người mới phát triển iOS. Những gì tôi đã làm là, tôi sử dụng chức năng để mở rộng UIImage, sau đó đặt nó theo chương trình bên trong func viewDidLoad. Hình ảnh này là từ điện thoại samsung photos.google.com/share/… và có dữ liệu exif hướng 270 CW. Dưới đây làm thế nào tôi sử dụng nólet background: UIImage? = UIImage(named: "background_image")?.fixOrientation() backgroundImage.image = background
HendraWD

Có ai gặp sự cố rò rỉ bộ nhớ khi sử dụng @Nicolas này không? có vẻ như Hình ảnh CGI không được phân bổ. Ứng dụng của tôi là một ứng dụng quản lý ảnh hàng loạt và xử lý nhiều ảnh. Chức năng này dường như bị rò rỉ bộ nhớ mỗi khi nó được chạy. Có bất kỳ bản sửa lỗi nhanh nào cho điều này không?
Michael Reilly,

@MichaelReilly Hmm, havne chưa xem xét chi tiết, nhưng các lệnh gọi CoreGraphics sẽ hoạt động nhanh chóng với ARC.
Nicolas Miari,

@MichaelReilly Tôi tìm thấy câu trả lời này, mà dường như để chứng thực sự quan sát của tôi: stackoverflow.com/a/25790214/433373
Nicolas Miari

24

Phương pháp này đầu tiên sẽ kiểm tra hướng hiện tại của UIImage và sau đó nó thay đổi hướng theo chiều kim đồng hồ và trả về UIImage. Bạn có thể hiển thị hình ảnh này dưới dạng

self.imageView.image = xoayImage (hình ảnh hiện tại)

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

Phiên bản 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
    }

Xin chào Varender và cảm ơn vì đã giúp đỡ trên SO. Bạn có thể phát triển một chút về cách bạn nghĩ rằng điều này có thể giúp Martin? Làm thế nào thanh lịch hơn so với dữ liệu luân phiên là giải pháp của bạn?
J. Chomel

1. chúng tôi sẽ lấy UIImage hiện tại từ UIImageView 2. chúng tôi sẽ gọi phương thức này (xoayImage) và chuyển UIImage hiện tại này làm đối số 3. lưu trữ giá trị trả về vào UIImageView.image / * điều này sẽ xoay dữ liệu trong chế độ xem hình ảnh: ) :)
varender singh

thưa ông theo tôi đó là câu trả lời tốt nhất vì nếu chúng ta xoay toàn bộ UIImageView thì UIImageView X là một giá trị âm. Nhưng nếu chúng ta xoay dữ liệu thì UIImageView sẽ giữ nguyên vị trí và chỉ dữ liệu được xoay. Nếu bạn sử dụng UIImageView hình vuông thì bạn chỉ cần chuyển đổi toàn bộ UIImageView bằng cách sử dụng CGAffineTransformMakeRotate.
varender singh

Đây phải là câu trả lời được chấp nhận! Làm việc như một nét duyên dáng :)
Ely Dantas

trong nhanh chóng 3: rotatedImage = UIImage (cgImage: image.cgImage !, quy mô: 1, định hướng: 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
}

Đây là một giải pháp hoàn hảo :)
giận hờn

bạn xứng đáng tất cả các bit bạn tôi
Mitchell Gant

Điều này tốt hơn thế . Điều này hoạt động trong nhanh chóng 4, nhưng điều đó không.
AechoLiu

Cảm ơn. Câu trả lời này hoạt động nếu bạn cần tải hình ảnh của mình lên máy chủ, không chỉ hiển thị như hầu hết các câu trả lời khác.
Nhà phát triển Nomad

hoạt động tốt. Lấy bất kỳ hình ảnh nào và lưu nó với định hướng
.up

9

Tiện ích mở rộng hình ảnh trong Swift. Bạn thực sự không cần phải làm tất cả những điều đó. Bản gốc Objective-C ở đây , nhưng tôi đã thêm một chút tôn trọng alpha của hình ảnh gốc (thô thiển, nhưng nó hoạt động để phân biệt hình ảnh mờ với hình ảnh trong suốt).

// 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

đây là một cod mẫu khả thi, xem xét hướng hình ảnh:

#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

Tôi đã chuyển đổi mã từ @Nicolas Miari answer thành Swift 3 trong trường hợp có ai cần nó

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;

}

Sau khi chụp ảnh trong đoàn phương pháp imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any] let imageCaptured:UIImage = info[UIImagePickerControllerOriginalImage] as! UIImage hình ảnh luôn luôn là rightOrientation và phương pháp này đang trở lại hình ảnh trở lại :(
Sumeet Mourya

Có định hướng hình ảnh là được. Được nhưng Nó hiển thị chính xác trên UIImageView. Apple có một số dữ liệu nội bộ được sử dụng ở đây để hiển thị corrrectly
Waseem05

4

Cảm ơn Waseem05 vì bản dịch Swift 3 của anh ấy nhưng phương pháp của anh ấy chỉ hiệu quả với tôi khi tôi bọc nó bên trong một phần mở rộng cho UIImage và đặt nó bên ngoài / bên dưới lớp cha như vậy:

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;

    }
}

Sau đó gọi nó bằng:

let correctedImage:UIImage = wonkyImage.fixOrientation()

Và tất cả sau đó đều tốt! Apple sẽ làm cho việc loại bỏ hướng dễ dàng hơn khi chúng ta không cần camera trước / sau và siêu dữ liệu hướng thiết bị lên / xuống / trái / phải.


4

Nếu bạn cần xoay và sửa hướng hình ảnh, phần mở rộng bên dưới sẽ hữu ích.

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. Tạo tiện ích mở rộng như ví dụ hàng đầu.
  2. Gọi nó: imageView.image?.fixImageOrientation()hoặcUIImage(named: "someImage").fixImageOrientation()

  3. Chúc tất cả may mắn!


Điều này hoạt động tốt. Nhưng bộ nhớ đang tích tụ giống như bất kỳ thứ gì và ứng dụng sẽ bị lỗi nếu điều này được gọi trong các vòng lặp.
abhimuralidharan

@abhimuralidharan, tôi đã không đăng ký lặp lại nó, nhưng 100% có một cách để áp dụng.
Mihail Salari

1

Phiên bản Swift 3.0 của câu trả lời của Tommy

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

0

Lấy cảm hứng từ @Aqua Answer .....

trong Mục tiêu C

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

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

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

   if (newImg) {
       return newImg;
   }

   return img;
}
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.