swift-video-generator
swift-video-generator copied to clipboard
UIImage.imageOrientation not honored
Images loaded by UIImagePickerController don't always have .imageOrientation set to UIImage.Orientation.up.
Transformations need to be applied accordingly before encoding them into the video.
Very rough, not well tested code that applies the orientation.
extension UIImage {
func fixedOrientation() -> UIImage {
guard imageOrientation != .up else {
return self
}
guard let cgImage = cgImage else {
return self
}
let w = size.width
let h = size.height
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
guard let ctx = CGContext(data: nil, width: Int(w), height: Int(h), bitsPerComponent: 8, bytesPerRow: Int(w) * 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) else {
return self
}
switch imageOrientation {
case .down, .downMirrored:
ctx.translateBy(x: w, y: h)
ctx.rotate(by: .pi)
case .left, .leftMirrored:
ctx.translateBy(x: w, y: 0)
ctx.rotate(by: .pi / 2.0)
case .right, .rightMirrored:
ctx.translateBy(x: 0, y: h)
ctx.rotate(by: -.pi / 2.0)
case .up, .upMirrored:
break
@unknown default:
return self
}
switch imageOrientation {
case .upMirrored, .downMirrored:
ctx.translateBy(x: size.width, y: 0)
ctx.scaleBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
ctx.translateBy(x: size.height, y: 0)
ctx.scaleBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
@unknown default:
return self
}
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: h, height: w))
default:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: w, height: h))
}
guard let resultCgImage: CGImage = ctx.makeImage() else {
return self
}
return UIImage(cgImage: resultCgImage)
}
}