[英]Swift: Images rotated from portrait to landscape when loaded from Firebase
Part of my iOS app uses Firebase Storage to store and load images taken/uploaded by the user.我的 iOS 应用程序的一部分使用 Firebase 存储来存储和加载用户拍摄/上传的图像。 However, every time I upload a picture to Firebase in portrait orientation, when I retrieve it back from Firebase later on it comes in landscape orientation and thus displays incorrectly.但是,每次我以纵向将图片上传到 Firebase 时,当我稍后从 Firebase 检索它时,它都会横向显示,因此显示不正确。
I've read that Firebase stores metadata to determine the correct orientation of an uploaded picture but it doesn't seem to be working for me.我读过 Firebase 存储元数据以确定上传图片的正确方向,但它似乎对我不起作用。
Any one know how to get the orientation the image was uploaded in without manually having to rotate it within the app's code?任何人都知道如何获得图像上传的方向而无需在应用程序代码中手动旋转它?
Thanks!谢谢!
edit for code:编辑代码:
Uploading:上传:
let imageMetaData = FIRStorageMetadata()
imageMetaData.contentType = "image/png"
var imageData = Data()
imageData = UIImagePNGRepresentation(chosenImage)!
let currentUserProfilePictureRef = currentUserStorageRef.child("ProfilePicture")
currentUserProfilePictureRef.put(imageData, metadata: imageMetaData) { (metaData, error) in
if error == nil {
let downloadUrl = metaData?.downloadURL()?.absoluteString
self.currentUserRef.updateChildValues(["profilePictureUrl": downloadUrl!])
if (chosenImage.size.width.isLess(than: (chosenImage.size.height))) {
self.currentUserRef.updateChildValues(["profilePictureOrientation": "portrait"])
}
else {
self.currentUserRef.updateChildValues(["profilePictureOrientation": "landscape"])
}
}
}
Retrieving:检索:
self.currentUserStorageRef.child("ProfilePicture").data(withMaxSize: 20*1024*1024, completion: {(data, error) in
var profilePicture = UIImage(data:data!)
if(profilePicture?.size.width.isLess(than: (profilePicture?.size.height)!))! {
if (pictureOrientation == "landscape") {
profilePicture = profilePicture?.rotated(by: Measurement(value: -90.0, unit: .degrees))
}
} else {
if (pictureOrientation == "portrait") {
profilePicture = profilePicture?.rotated(by: Measurement(value: 90.0, unit: .degrees))
}
}
self.buttonProfilePicture.setImage(profilePicture, for: .normal)
self.buttonProfilePicture.imageView?.contentMode = .scaleAspectFill
})
From my own personal experience (and asking virtually the same question a year ago), I've found that when you save an image using UIImagePNGRepresentation
, it doesn't actually store the orientation data for that specific image.根据我自己的个人经验(并且在一年前问过几乎相同的问题),我发现当您使用UIImagePNGRepresentation
保存图像时,它实际上并没有存储该特定图像的方向数据。 You should use UIImageJPEGRepresentation
when you're having orientation issues.当您遇到方向问题时,您应该使用UIImageJPEGRepresentation
。 JPEG
uses the exif
format that specifies the orientation for an image, whereas PNG
apparently does not. JPEG
使用指定图像方向的exif
格式,而PNG
显然没有。 Your issue should be resolved if you save your image using UIImageJPEGRepresentation
如果您使用UIImageJPEGRepresentation
保存图像,您的问题应该会得到解决
Swift 5 - Update Swift 5 - 更新
This worked for me, just apply this on your UIImage before uploading it.这对我有用,只需在上传之前将其应用于您的 UIImage 即可。
extension UIImage {
func fixedOrientation() -> UIImage? {
guard imageOrientation != UIImage.Orientation.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)
case .left, .leftMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.rotated(by: CGFloat.pi / 2.0)
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: size.height)
transform = transform.rotated(by: CGFloat.pi / -2.0)
case .up, .upMirrored:
break
@unknown default:
break
}
// Flip image one more time if needed to, this is to prevent flipped image
switch imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: size.height, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
case .up, .down, .left, .right:
break
@unknown default:
break
}
ctx.concatenate(transform)
switch imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
default:
ctx.draw(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)
}
} }
Just an update, UIImageJPEGRepresentation has changed to jpegData in the recent versions of xcode.只是一个更新,UIImageJPEGRepresentation 在最新版本的 xcode 中已更改为 jpegData。
jpegData(compressionQuality: 1.0) 1.0 being high quality and 0 being low quality. jpegData(compressionQuality: 1.0) 1.0 为高质量,0 为低质量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.