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, "mediumType" to imageType,
"width" to width, "width" to width,
"height" to height, "height" to height,
"orientation" to orientation, "orientation" to orientationDegree2Value(orientation),
"mimeType" to mimeType, "mimeType" to mimeType,
"creationDate" to dateTaken, "creationDate" to dateTaken,
"modifiedDate" to dateModified "modifiedDate" to dateModified
@ -852,7 +852,7 @@ class PhotoGalleryPlugin : FlutterPlugin, MethodCallHandler {
"id" to id.toString(), "id" to id.toString(),
"mediumType" to videoType, "mediumType" to videoType,
"width" to width, "width" to width,
"orientation" to orientation, "orientation" to orientationDegree2Value(orientation),
"height" to height, "height" to height,
"mimeType" to mimeType, "mimeType" to mimeType,
"duration" to duration, "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? { private fun getCachePath(): File? {
return this.context?.run { return this.context?.run {
val cachePath = File(this.cacheDir, "photo_gallery") 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) 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] let asset: PHAsset = assets[0]
completion(getMediumFromAsset(asset: asset), nil) getMediumFromAssetAsync(
return 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( private func getThumbnail(
@ -423,6 +427,28 @@ public class SwiftPhotoGalleryPlugin: NSObject, FlutterPlugin {
"modifiedDate": (asset.modificationDate != nil) ? NSInteger(asset.modificationDate!.timeIntervalSince1970 * 1000) : nil "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 { private func exportPathForAsset(asset: PHAsset, ext: String) -> URL {
let mediumId = asset.localIdentifier 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 { private func predicateFromMediumTypes(mediumTypes: [String]) -> NSPredicate {
let predicates = mediumTypes.map { (dartValue) -> NSPredicate in let predicates = mediumTypes.map { (dartValue) -> NSPredicate in
return predicateFromMediumType(mediumType: dartValue) return predicateFromMediumType(mediumType: dartValue)