0

In my app, the user selects an image from the photo library, and then it goes to a cell in a collection cell. The cell contains only the ImageView. When the image is shown, if it is an image took with the front camera, it rotates to the 90 degrees to the right if it is portrait, and 180 if it is landscape.

I tried with this extension, but it didn't work. Also tried changing the image content mode to: aspect fill, aspect fit, scale to fill. But nothing.

func fixedOrientation() -> UIImage? {

    guard imageOrientation != UIImageOrientation.up else {
        //This is default orientation, don't need to do anything
        return self.copy() as? UIImage
    }

    guard let cgImage = self.cgImage else {
        //CGImage is not available
        return nil
    }

    guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
        return nil //Not able to create CGContext
    }

    var transform: CGAffineTransform = CGAffineTransform.identity

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

    //Flip image one more time if needed to, this is to prevent flipped image
    switch imageOrientation {
    case .upMirrored, .downMirrored:
        transform.translatedBy(x: size.width, y: 0)
        transform.scaledBy(x: -1, y: 1)
        break
    case .leftMirrored, .rightMirrored:
        transform.translatedBy(x: size.height, y: 0)
        transform.scaledBy(x: -1, y: 1)
    case .up, .down, .left, .right:
        break
    }

    ctx.concatenate(transform)

    switch imageOrientation {
    case .left, .leftMirrored, .right, .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
    }

    guard let newCGImage = ctx.makeImage() else { return nil }
    return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
}
  • Are you saving your images as PNG? – Leo Dabus Apr 13 '18 at 22:43
  • yes, this is what I do: let imageData: NSData = UIImagePNGRepresentation(image)! as NSData – Alejandro Robles Apr 14 '18 at 22:13
  • PNG has no metadata so it discards the image orientation. You have two options. 1) save it as jpeg using UIImageJPEGRepresentation (best option considering the final size of the image) 2) Flatten your image redrawing it as you can see in this answer https://stackoverflow.com/questions/42098390/swift-png-image-being-saved-with-incorrect-orientation/42098812#42098812 – Leo Dabus Apr 15 '18 at 10:08
  • 1
    @LeoDabus thank you so much, it works with jpeg! – Alejandro Robles Apr 15 '18 at 15:18

0 Answers0