convert orientation property value of medium to satisfy EXIF standard both on Android and iOS (on iOS, provide orientation property only when get single medium rather than list media)

This commit is contained in:
Wenqi Li 2021-10-20 19:37:38 +08:00
parent 35999af628
commit 50d9070995
2 changed files with 66 additions and 7 deletions

View File

@ -816,7 +816,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
"mediumType" to imageType,
"width" to width,
"height" to height,
"orientation" to orientation,
"orientation" to orientationDegree2Value(orientation),
"mimeType" to mimeType,
"creationDate" to dateTaken,
"modifiedDate" to dateModified
@ -852,7 +852,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
"id" to id.toString(),
"mediumType" to videoType,
"width" to width,
"orientation" to orientation,
"orientation" to orientationDegree2Value(orientation),
"height" to height,
"mimeType" to mimeType,
"duration" to duration,
@ -861,6 +861,16 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
)
}
private fun orientationDegree2Value(degree: Long): Int {
return when (degree) {
0L -> 1
90L -> 8
180L -> 3
270L -> 6
else -> 0
}
}
private fun getCachePath(): File? {
return this.context?.run {
val cachePath = File(this.cacheDir, "photo_gallery")

View File

@ -211,13 +211,17 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
}
let assets: PHFetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [mediumId], options: fetchOptions)
if (assets.count > 0) {
if (assets.count <= 0) {
completion(nil, NSError(domain: "photo_gallery", code: 404, userInfo: nil))
} else {
let asset: PHAsset = assets[0]
completion(getMediumFromAsset(asset: asset), nil)
return
getMediumFromAssetAsync(
asset: asset,
completion: { (data: [String: Any?]?, error: Error?) -> Void in
completion(data, nil)
}
)
}
completion(nil, NSError(domain: "photo_gallery", code: 404, userInfo: nil))
}
private func getThumbnail(
@ -423,6 +427,28 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
"modifiedDate": (asset.modificationDate != nil) ? NSInteger(asset.modificationDate!.timeIntervalSince1970 * 1000) : nil
]
}
private func getMediumFromAssetAsync(asset: PHAsset, completion: @escaping ([String : Any?]?, Error?) -> Void) -> Void {
let mimeType = self.extractMimeTypeFromAsset(asset: asset)
let manager = PHImageManager.default()
manager.requestImageData(
for: asset,
options: nil,
resultHandler: { (data: Data?, uti: String?, orientation: UIImage.Orientation, info: ([AnyHashable: Any]?)) -> Void in
completion([
"id": asset.localIdentifier,
"mediumType": self.toDartMediumType(value: asset.mediaType),
"mimeType": mimeType,
"height": asset.pixelHeight,
"width": asset.pixelWidth,
"orientation": self.toOrientationValue(orientation: orientation),
"duration": NSInteger(asset.duration * 1000),
"creationDate": (asset.creationDate != nil) ? NSInteger(asset.creationDate!.timeIntervalSince1970 * 1000) : nil,
"modifiedDate": (asset.modificationDate != nil) ? NSInteger(asset.modificationDate!.timeIntervalSince1970 * 1000) : nil
], nil)
}
)
}
private func exportPathForAsset(asset: PHAsset, ext: String) -> URL {
let mediumId = asset.localIdentifier
@ -450,6 +476,29 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
}
}
private func toOrientationValue(orientation: UIImage.Orientation) -> Int {
switch orientation {
case UIImage.Orientation.up:
return 1
case UIImage.Orientation.down:
return 3
case UIImage.Orientation.left:
return 6
case UIImage.Orientation.right:
return 8
case UIImage.Orientation.upMirrored:
return 2
case UIImage.Orientation.downMirrored:
return 4
case UIImage.Orientation.leftMirrored:
return 5
case UIImage.Orientation.rightMirrored:
return 7
@unknown default:
return 0
}
}
private func predicateFromMediumTypes(mediumTypes: [String]) -> NSPredicate {
let predicates = mediumTypes.map { (dartValue) -> NSPredicate in
return predicateFromMediumType(mediumType: dartValue)