我的部分iOS应用使用Firebase存储来存储和加载用户拍摄/上传的图像。 但是,每次我以纵向方式将图片上传到Firebase时,当我稍后从Firebase检索它时,它会以横向方向显示,从而显示不正确。
我已经读过Firebase存储元数据以确定上传图片的正确方向,但它似乎对我不起作用。
任何人都知道如何在不需要在应用程序代码中手动旋转图像的情况下获取图像的方向?
谢谢!
编辑代码:
上传:
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"])
}
}
}
检索:
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
})
答案 0 :(得分:8)
根据我个人的经验(并在一年前询问几乎相同的问题),我发现当您使用UIImagePNGRepresentation
保存图像时,它实际上并不存储该特定图像的方向数据。当您遇到方向问题时,您应该使用UIImageJPEGRepresentation
。 JPEG
使用指定图片方向的exif
格式,而PNG
显然不会。如果您使用UIImageJPEGRepresentation
答案 1 :(得分:2)
Swift 5-更新
这对我有用,只需在上传之前将其应用于您的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)
}
}
答案 2 :(得分:1)
只是更新,在最新版本的xcode中,UIImageJPEGRepresentation已更改为jpegData。
jpegData(compressionQuality:1.0)1.0为高质量,0为低质量。