terikon / cordova-plugin-photo-library

Maintainer needed. Please contact if you're using this library in your project
MIT License
149 stars 296 forks source link

ios rotated photo issue #146

Open musashiM82 opened 5 years ago

musashiM82 commented 5 years ago

hi all

I have an issue when I read the photoURL of photos in portrait mode on ios. As you can see, the following json is an example of a portrait photo returned by getLibrary method { "id":"3F9305DB-5507-4941-8231-97C8A2481916/L0/001", "fileName":"IMG_0168.JPG", "mimeType":"image/jpeg", "filePath":"/var/mobile/Media/DCIM/100APPLE/IMG_0168.JPG", "width":2448, "creationDate":"2018-08-25T15:18:55.320Z", "height":3264, "thumbnailURL":"cdvphotolibrary://thumbnail?photoId=3F9305DB-5507-4941-8231-97C8A2481916%2FL0%2F001&width=100&height=100&quality=0.7", "photoURL":"cdvphotolibrary://photo?photoId=3F9305DB-5507-4941-8231-97C8A2481916%2FL0%2F001" } width is 2448, height is 3264, thumbnail have the correct orientation, but when I show the photoURL the photo is rotated.

How can I solve this issue?

thanks in advance

benkhlifafahmi commented 5 years ago

Hi, i faced this problem on IOS devices what i did was adding the following extension to the PhotoLibraryService.swift just under the PHAsset extension :

extension UIImage {

    func fixedOrientation() -> UIImage {

        if imageOrientation == .up {
            return self
        }

        var transform: CGAffineTransform = CGAffineTransform.identity

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

        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
        }

        let ctx: CGContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: (self.cgImage?.colorSpace)!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!

        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))
            break
        default:
            ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            break
        }

        let cgImage: CGImage = ctx.makeImage()!

        return UIImage(cgImage: cgImage)
    }
}

and changed the method getPhoto so it become like this :

func getPhoto(_ photoId: String, completion: @escaping (_ result: PictureData?) -> Void) {

        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [photoId], options: self.fetchOptions)

        if fetchResult.count == 0 {
            completion(nil)
            return
        }

        fetchResult.enumerateObjects({
            (obj: AnyObject, idx: Int, stop: UnsafeMutablePointer<ObjCBool>) -> Void in

            let asset = obj as! PHAsset

            PHImageManager.default().requestImageData(for: asset, options: self.imageRequestOptions) {
                (imageData: Data?, dataUTI: String?, orientation: UIImageOrientation, info: [AnyHashable: Any]?) in

                guard let image = imageData != nil ? UIImage(data: imageData!) : nil else {
                    completion(nil)
                    return
                }

                let imageData = PhotoLibraryService.image2PictureData(image.fixedOrientation(), quality: 1.0)

                completion(imageData)
            }
        })

and inside my JS once i need to get a file i simply use the getPhoto function to get the file in the correct orientation, you can use this as temporary solution till they fix it.

Regards, Ben