fixed opening panorama with non-gpano xmp namespace

This commit is contained in:
Thibault Deckers 2021-02-27 19:08:24 +09:00
parent 8fb349fc6e
commit e25a1eefb9
3 changed files with 55 additions and 27 deletions

View file

@ -47,7 +47,9 @@ import deckers.thibault.aves.metadata.MetadataExtractorHelper.getSafeRational
import deckers.thibault.aves.metadata.MetadataExtractorHelper.getSafeString import deckers.thibault.aves.metadata.MetadataExtractorHelper.getSafeString
import deckers.thibault.aves.metadata.MetadataExtractorHelper.isGeoTiff import deckers.thibault.aves.metadata.MetadataExtractorHelper.isGeoTiff
import deckers.thibault.aves.metadata.XMP.getSafeDateMillis import deckers.thibault.aves.metadata.XMP.getSafeDateMillis
import deckers.thibault.aves.metadata.XMP.getSafeInt
import deckers.thibault.aves.metadata.XMP.getSafeLocalizedText import deckers.thibault.aves.metadata.XMP.getSafeLocalizedText
import deckers.thibault.aves.metadata.XMP.getSafeString
import deckers.thibault.aves.metadata.XMP.isPanorama import deckers.thibault.aves.metadata.XMP.isPanorama
import deckers.thibault.aves.model.FieldMap import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.model.provider.FileImageProvider import deckers.thibault.aves.model.provider.FileImageProvider
@ -627,25 +629,21 @@ class MetadataHandler(private val context: Context) : MethodCallHandler {
try { try {
Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input -> Metadata.openSafeInputStream(context, uri, mimeType, sizeBytes)?.use { input ->
val metadata = ImageMetadataReader.readMetadata(input) val metadata = ImageMetadataReader.readMetadata(input)
val xmpDirs = metadata.getDirectoriesOfType(XmpDirectory::class.java) val fields = hashMapOf<String, Any?>(
try { "projectionType" to XMP.GPANO_PROJECTION_TYPE_DEFAULT,
fun getIntProp(propName: String): Int? = xmpDirs.map { it.xmpMeta.getPropertyInteger(XMP.GPANO_SCHEMA_NS, propName) }.firstOrNull { it != null }
fun getStringProp(propName: String): String? = xmpDirs.map { it.xmpMeta.getPropertyString(XMP.GPANO_SCHEMA_NS, propName) }.firstOrNull { it != null }
val fields: FieldMap = hashMapOf(
"croppedAreaLeft" to getIntProp(XMP.GPANO_CROPPED_AREA_LEFT_PROP_NAME),
"croppedAreaTop" to getIntProp(XMP.GPANO_CROPPED_AREA_TOP_PROP_NAME),
"croppedAreaWidth" to getIntProp(XMP.GPANO_CROPPED_AREA_WIDTH_PROP_NAME),
"croppedAreaHeight" to getIntProp(XMP.GPANO_CROPPED_AREA_HEIGHT_PROP_NAME),
"fullPanoWidth" to getIntProp(XMP.GPANO_FULL_PANO_WIDTH_PROP_NAME),
"fullPanoHeight" to getIntProp(XMP.GPANO_FULL_PANO_HEIGHT_PROP_NAME),
"projectionType" to (getStringProp(XMP.GPANO_PROJECTION_TYPE_PROP_NAME) ?: XMP.GPANO_PROJECTION_TYPE_DEFAULT),
) )
for (dir in metadata.getDirectoriesOfType(XmpDirectory::class.java)) {
val xmpMeta = dir.xmpMeta
xmpMeta.getSafeInt(XMP.GPANO_SCHEMA_NS, XMP.GPANO_CROPPED_AREA_LEFT_PROP_NAME) { fields["croppedAreaLeft"] = it }
xmpMeta.getSafeInt(XMP.GPANO_SCHEMA_NS, XMP.GPANO_CROPPED_AREA_TOP_PROP_NAME) { fields["croppedAreaTop"] = it }
xmpMeta.getSafeInt(XMP.GPANO_SCHEMA_NS, XMP.GPANO_CROPPED_AREA_WIDTH_PROP_NAME) { fields["croppedAreaWidth"] = it }
xmpMeta.getSafeInt(XMP.GPANO_SCHEMA_NS, XMP.GPANO_CROPPED_AREA_HEIGHT_PROP_NAME) { fields["croppedAreaHeight"] = it }
xmpMeta.getSafeInt(XMP.GPANO_SCHEMA_NS, XMP.GPANO_FULL_PANO_WIDTH_PROP_NAME) { fields["fullPanoWidth"] = it }
xmpMeta.getSafeInt(XMP.GPANO_SCHEMA_NS, XMP.GPANO_FULL_PANO_HEIGHT_PROP_NAME) { fields["fullPanoHeight"] = it }
xmpMeta.getSafeString(XMP.GPANO_SCHEMA_NS, XMP.GPANO_PROJECTION_TYPE_PROP_NAME) { fields["projectionType"] = it }
}
result.success(fields) result.success(fields)
return return
} catch (e: XMPException) {
result.error("getPanoramaInfo-args", "failed to read XMP for uri=$uri", e.message)
return
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.w(LOG_TAG, "failed to read XMP", e) Log.w(LOG_TAG, "failed to read XMP", e)

View file

@ -97,6 +97,34 @@ object XMP {
return false return false
} }
fun XMPMeta.getSafeInt(schema: String, propName: String, save: (value: Int) -> Unit) {
try {
if (doesPropertyExist(schema, propName)) {
val item = getPropertyInteger(schema, propName)
// double check retrieved items as the property sometimes is reported to exist but it is actually null
if (item != null) {
save(item)
}
}
} catch (e: XMPException) {
Log.w(LOG_TAG, "failed to get int for XMP schema=$schema, propName=$propName", e)
}
}
fun XMPMeta.getSafeString(schema: String, propName: String, save: (value: String) -> Unit) {
try {
if (doesPropertyExist(schema, propName)) {
val item = getPropertyString(schema, propName)
// double check retrieved items as the property sometimes is reported to exist but it is actually null
if (item != null) {
save(item)
}
}
} catch (e: XMPException) {
Log.w(LOG_TAG, "failed to get int for XMP schema=$schema, propName=$propName", e)
}
}
fun XMPMeta.getSafeLocalizedText(schema: String, propName: String, acceptBlank: Boolean = true, save: (value: String) -> Unit) { fun XMPMeta.getSafeLocalizedText(schema: String, propName: String, acceptBlank: Boolean = true, save: (value: String) -> Unit) {
try { try {
if (doesPropertyExist(schema, propName)) { if (doesPropertyExist(schema, propName)) {

View file

@ -25,6 +25,7 @@ class PanoramaOverlay extends StatelessWidget {
text: 'Open Panorama', text: 'Open Panorama',
onPressed: () async { onPressed: () async {
final info = await MetadataService.getPanoramaInfo(entry); final info = await MetadataService.getPanoramaInfo(entry);
if (info != null) {
unawaited(Navigator.push( unawaited(Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@ -35,6 +36,7 @@ class PanoramaOverlay extends StatelessWidget {
), ),
), ),
)); ));
}
}, },
) )
], ],