collection: identify Photomatix panoramas
This commit is contained in:
parent
25ebc95d42
commit
9e13fdeea7
3 changed files with 26 additions and 11 deletions
|
@ -43,6 +43,7 @@ import deckers.thibault.aves.metadata.MetadataExtractorHelper.isGeoTiff
|
|||
import deckers.thibault.aves.metadata.XMP
|
||||
import deckers.thibault.aves.metadata.XMP.getSafeDateMillis
|
||||
import deckers.thibault.aves.metadata.XMP.getSafeLocalizedText
|
||||
import deckers.thibault.aves.metadata.XMP.isPanorama
|
||||
import deckers.thibault.aves.model.provider.FieldMap
|
||||
import deckers.thibault.aves.model.provider.FileImageProvider
|
||||
import deckers.thibault.aves.model.provider.ImageProvider
|
||||
|
@ -298,9 +299,9 @@ class MetadataHandler(private val context: Context) : MethodCallHandler {
|
|||
val values = (1 until count + 1).map { xmpMeta.getArrayItem(XMP.DC_SCHEMA_NS, XMP.SUBJECT_PROP_NAME, it).value }
|
||||
metadataMap[KEY_XMP_SUBJECTS] = values.joinToString(separator = XMP_SUBJECTS_SEPARATOR)
|
||||
}
|
||||
xmpMeta.getSafeLocalizedText(XMP.DC_SCHEMA_NS, XMP.TITLE_PROP_NAME) { metadataMap[KEY_XMP_TITLE_DESCRIPTION] = it }
|
||||
xmpMeta.getSafeLocalizedText(XMP.DC_SCHEMA_NS, XMP.TITLE_PROP_NAME, acceptBlank = false) { metadataMap[KEY_XMP_TITLE_DESCRIPTION] = it }
|
||||
if (!metadataMap.containsKey(KEY_XMP_TITLE_DESCRIPTION)) {
|
||||
xmpMeta.getSafeLocalizedText(XMP.DC_SCHEMA_NS, XMP.DESCRIPTION_PROP_NAME) { metadataMap[KEY_XMP_TITLE_DESCRIPTION] = it }
|
||||
xmpMeta.getSafeLocalizedText(XMP.DC_SCHEMA_NS, XMP.DESCRIPTION_PROP_NAME, acceptBlank = false) { metadataMap[KEY_XMP_TITLE_DESCRIPTION] = it }
|
||||
}
|
||||
if (!metadataMap.containsKey(KEY_DATE_MILLIS)) {
|
||||
xmpMeta.getSafeDateMillis(XMP.XMP_SCHEMA_NS, XMP.CREATE_DATE_PROP_NAME) { metadataMap[KEY_DATE_MILLIS] = it }
|
||||
|
@ -310,7 +311,7 @@ class MetadataHandler(private val context: Context) : MethodCallHandler {
|
|||
}
|
||||
|
||||
// identification of panorama (aka photo sphere)
|
||||
if (XMP.panoramaRequiredProps.all { xmpMeta.doesPropertyExist(XMP.GPANO_SCHEMA_NS, it) }) {
|
||||
if (xmpMeta.isPanorama()) {
|
||||
flags = flags or MASK_IS_360
|
||||
}
|
||||
} catch (e: XMPException) {
|
||||
|
|
|
@ -42,7 +42,8 @@ object XMP {
|
|||
// panorama
|
||||
// cf https://developers.google.com/streetview/spherical-metadata
|
||||
|
||||
const val GPANO_SCHEMA_NS = "http://ns.google.com/photos/1.0/panorama/"
|
||||
private const val GPANO_SCHEMA_NS = "http://ns.google.com/photos/1.0/panorama/"
|
||||
private const val PMTM_SCHEMA_NS = "http://www.hdrsoft.com/photomatix_settings01"
|
||||
|
||||
private const val GPANO_CROPPED_AREA_HEIGHT_PROP_NAME = "GPano:CroppedAreaImageHeightPixels"
|
||||
private const val GPANO_CROPPED_AREA_WIDTH_PROP_NAME = "GPano:CroppedAreaImageWidthPixels"
|
||||
|
@ -52,7 +53,9 @@ object XMP {
|
|||
private const val GPANO_FULL_PANO_WIDTH_PIXELS_PROP_NAME = "GPano:FullPanoWidthPixels"
|
||||
private const val GPANO_PROJECTION_TYPE_PROP_NAME = "GPano:ProjectionType"
|
||||
|
||||
val panoramaRequiredProps = listOf(
|
||||
private const val PMTM_IS_PANO360 = "pmtm:IsPano360"
|
||||
|
||||
private val gpanoRequiredProps = listOf(
|
||||
GPANO_CROPPED_AREA_HEIGHT_PROP_NAME,
|
||||
GPANO_CROPPED_AREA_WIDTH_PROP_NAME,
|
||||
GPANO_CROPPED_AREA_LEFT_PROP_NAME,
|
||||
|
@ -64,12 +67,22 @@ object XMP {
|
|||
|
||||
// extensions
|
||||
|
||||
fun XMPMeta.getSafeLocalizedText(schema: String, propName: String, save: (value: String) -> Unit) {
|
||||
fun XMPMeta.isPanorama(): Boolean {
|
||||
// Google
|
||||
if (gpanoRequiredProps.all { doesPropertyExist(GPANO_SCHEMA_NS, it) }) return true
|
||||
// Photomatix
|
||||
if (getPropertyString(PMTM_SCHEMA_NS, PMTM_IS_PANO360) == "Yes") return true
|
||||
return false
|
||||
}
|
||||
|
||||
fun XMPMeta.getSafeLocalizedText(schema: String, propName: String, acceptBlank: Boolean = true, save: (value: String) -> Unit) {
|
||||
try {
|
||||
if (this.doesPropertyExist(schema, propName)) {
|
||||
val item = this.getLocalizedText(schema, propName, GENERIC_LANG, SPECIFIC_LANG)
|
||||
if (doesPropertyExist(schema, propName)) {
|
||||
val item = getLocalizedText(schema, propName, GENERIC_LANG, SPECIFIC_LANG)
|
||||
// double check retrieved items as the property sometimes is reported to exist but it is actually null
|
||||
if (item != null) save(item.value)
|
||||
if (item != null && (acceptBlank || item.value.isNotBlank())) {
|
||||
save(item.value)
|
||||
}
|
||||
}
|
||||
} catch (e: XMPException) {
|
||||
Log.w(LOG_TAG, "failed to get text for XMP schema=$schema, propName=$propName", e)
|
||||
|
@ -78,8 +91,8 @@ object XMP {
|
|||
|
||||
fun XMPMeta.getSafeDateMillis(schema: String, propName: String, save: (value: Long) -> Unit) {
|
||||
try {
|
||||
if (this.doesPropertyExist(schema, propName)) {
|
||||
val item = this.getPropertyDate(schema, propName)
|
||||
if (doesPropertyExist(schema, propName)) {
|
||||
val item = getPropertyDate(schema, propName)
|
||||
// double check retrieved items as the property sometimes is reported to exist but it is actually null
|
||||
if (item != null) {
|
||||
// strip time zone from XMP dates so that we show date/times as local ones
|
||||
|
|
|
@ -25,6 +25,7 @@ class XMP {
|
|||
'PanoStudioXMP': 'PanoramaStudio',
|
||||
'photomechanic': 'Photo Mechanic',
|
||||
'plus': 'PLUS',
|
||||
'pmtm': 'Photomatix',
|
||||
'xmpBJ': 'Basic Job Ticket',
|
||||
'xmpDM': 'Dynamic Media',
|
||||
'xmpRights': 'Rights Management',
|
||||
|
|
Loading…
Reference in a new issue