简体   繁体   English

Swift:从 Firebase 加载时图像从纵向旋转到横向

[英]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.

相关问题 UITableView在从纵向旋转到横向再回到纵向时更改大小 - UITableView changes sizes when rotated from portrait, to landscape, back to portrait 从纵向旋转到横向模式时,搜索栏会丢失FirstResponder - Search Bar Loses FirstResponder when rotated from Portrait to Landscape mode UISplitViewController主面板显示的视图在从纵向旋转到横向时不旋转(iPad) - View presented from master panel of UISplitViewController not rotating when rotated from portrait to landscape (iPad) 从纵向模式转到横向模式时,屏幕上的图像放置不正确? - Images on screen are not placed well when going from portrait to landscape mode? 在iOS中将屏幕从纵向旋转为横向时,如何获取textView展开 - How do I get a textView to expand when screen is rotated from portrait to landscape in iOS 在旋转的横向监视器上显示手机的肖像视图 - Presenting an portrait view from phone on an rotated landscape monitor CMSampleBuffer 在 Swift 3 中从纵向旋转到横向 - CMSampleBuffer rotate from portrait to landscape in Swift 3 Swift 3:tableView复制Firebase中加载的图像 - Swift 3 : tableView duplicating loaded images from Firebase popViewControllerAnimated:从横向到纵向 - popViewControllerAnimated: From Landscape To Portrait UICollectionView从纵向到横向 - UICollectionView from portrait to landscape
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM