info: improved DNG tags display
This commit is contained in:
parent
2cbeff39c4
commit
fa862c041e
7 changed files with 175 additions and 163 deletions
|
@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Theme: light/dark/black and poly/monochrome settings
|
||||
- Video: speed and muted state indicators
|
||||
- Info: option to set date from other item
|
||||
- Info: improved DNG tags display
|
||||
- warn and optionally set metadata date before moving undated items
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -74,7 +74,10 @@ import deckers.thibault.aves.utils.UriUtils.tryParseId
|
|||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.text.ParseException
|
||||
|
@ -163,15 +166,24 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
|
|||
// tags
|
||||
val tags = dir.tags
|
||||
if (dir is ExifDirectoryBase) {
|
||||
if (dir.isGeoTiff()) {
|
||||
when {
|
||||
dir.isGeoTiff() -> {
|
||||
// split GeoTIFF tags in their own directory
|
||||
val geoTiffDirMap = metadataMap["GeoTIFF"] ?: HashMap()
|
||||
metadataMap["GeoTIFF"] = geoTiffDirMap
|
||||
val byGeoTiff = tags.groupBy { ExifTags.isGeoTiffTag(it.tagType) }
|
||||
metadataMap["GeoTIFF"] = HashMap<String, String>().apply {
|
||||
byGeoTiff[true]?.map { exifTagMapper(it) }?.let { putAll(it) }
|
||||
}
|
||||
byGeoTiff[true]?.map { exifTagMapper(it) }?.let { geoTiffDirMap.putAll(it) }
|
||||
byGeoTiff[false]?.map { exifTagMapper(it) }?.let { dirMap.putAll(it) }
|
||||
} else {
|
||||
dirMap.putAll(tags.map { exifTagMapper(it) })
|
||||
}
|
||||
mimeType == MimeTypes.DNG -> {
|
||||
// split DNG tags in their own directory
|
||||
val dngDirMap = metadataMap["DNG"] ?: HashMap()
|
||||
metadataMap["DNG"] = dngDirMap
|
||||
val byDng = tags.groupBy { ExifTags.isDngTag(it.tagType) }
|
||||
byDng[true]?.map { exifTagMapper(it) }?.let { dngDirMap.putAll(it) }
|
||||
byDng[false]?.map { exifTagMapper(it) }?.let { dirMap.putAll(it) }
|
||||
}
|
||||
else -> dirMap.putAll(tags.map { exifTagMapper(it) })
|
||||
}
|
||||
} else if (dir.isPngTextDir()) {
|
||||
metadataMap.remove(thisDirName)
|
||||
|
|
|
@ -224,4 +224,6 @@ object DngTags {
|
|||
REDUCTION_MATRIX_3 to "Reduction Matrix 3",
|
||||
RGB_TABLES to "RGB Tables",
|
||||
)
|
||||
|
||||
val tags = tagNameMap.keys
|
||||
}
|
||||
|
|
|
@ -49,46 +49,6 @@ object ExifTags {
|
|||
// obsoleted by the 6.0 ExtraSamples (338)
|
||||
private const val TAG_MATTEING = 0x80e3
|
||||
|
||||
/*
|
||||
GeoTIFF
|
||||
*/
|
||||
|
||||
// ModelPixelScaleTag (optional)
|
||||
// Tag = 33550 (830E.H)
|
||||
// Type = DOUBLE
|
||||
// Count = 3
|
||||
const val TAG_MODEL_PIXEL_SCALE = 0x830e
|
||||
|
||||
// ModelTiepointTag (conditional)
|
||||
// Tag = 33922 (8482.H)
|
||||
// Type = DOUBLE
|
||||
// Count = 6*K, K = number of tiepoints
|
||||
const val TAG_MODEL_TIEPOINT = 0x8482
|
||||
|
||||
// ModelTransformationTag (conditional)
|
||||
// Tag = 34264 (85D8.H)
|
||||
// Type = DOUBLE
|
||||
// Count = 16
|
||||
const val TAG_MODEL_TRANSFORMATION = 0x85d8
|
||||
|
||||
// GeoKeyDirectoryTag (mandatory)
|
||||
// Tag = 34735 (87AF.H)
|
||||
// Type = UNSIGNED SHORT
|
||||
// Count = variable, >= 4
|
||||
const val TAG_GEO_KEY_DIRECTORY = 0x87af
|
||||
|
||||
// GeoDoubleParamsTag (optional)
|
||||
// Tag = 34736 (87BO.H)
|
||||
// Type = DOUBLE
|
||||
// Count = variable
|
||||
private const val TAG_GEO_DOUBLE_PARAMS = 0x87b0
|
||||
|
||||
// GeoAsciiParamsTag (optional)
|
||||
// Tag = 34737 (87B1.H)
|
||||
// Type = ASCII
|
||||
// Count = variable
|
||||
private const val TAG_GEO_ASCII_PARAMS = 0x87b1
|
||||
|
||||
/*
|
||||
Photoshop
|
||||
https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
|
||||
|
@ -100,15 +60,6 @@ object ExifTags {
|
|||
// Type = UNDEFINED
|
||||
private const val TAG_IMAGE_SOURCE_DATA = 0x935c
|
||||
|
||||
private val geotiffTags = listOf(
|
||||
TAG_GEO_ASCII_PARAMS,
|
||||
TAG_GEO_DOUBLE_PARAMS,
|
||||
TAG_GEO_KEY_DIRECTORY,
|
||||
TAG_MODEL_PIXEL_SCALE,
|
||||
TAG_MODEL_TIEPOINT,
|
||||
TAG_MODEL_TRANSFORMATION,
|
||||
)
|
||||
|
||||
private val tagNameMap = hashMapOf(
|
||||
TAG_X_POSITION to "X Position",
|
||||
TAG_Y_POSITION to "Y Position",
|
||||
|
@ -118,20 +69,16 @@ object ExifTags {
|
|||
TAG_RATING_PERCENT to "Rating Percent",
|
||||
// SGI
|
||||
TAG_MATTEING to "Matteing",
|
||||
// GeoTIFF
|
||||
TAG_GEO_ASCII_PARAMS to "Geo Ascii Params",
|
||||
TAG_GEO_DOUBLE_PARAMS to "Geo Double Params",
|
||||
TAG_GEO_KEY_DIRECTORY to "Geo Key Directory",
|
||||
TAG_MODEL_PIXEL_SCALE to "Model Pixel Scale",
|
||||
TAG_MODEL_TIEPOINT to "Model Tiepoint",
|
||||
TAG_MODEL_TRANSFORMATION to "Model Transformation",
|
||||
// Photoshop
|
||||
TAG_IMAGE_SOURCE_DATA to "Image Source Data",
|
||||
).apply {
|
||||
putAll(DngTags.tagNameMap)
|
||||
putAll(GeoTiffTags.tagNameMap)
|
||||
}
|
||||
|
||||
fun isGeoTiffTag(tag: Int) = geotiffTags.contains(tag)
|
||||
fun isDngTag(tag: Int) = DngTags.tags.contains(tag)
|
||||
|
||||
fun isGeoTiffTag(tag: Int) = GeoTiffTags.tags.contains(tag)
|
||||
|
||||
fun getTagName(tag: Int): String? {
|
||||
return tagNameMap[tag]
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package deckers.thibault.aves.metadata
|
||||
|
||||
object GeoTiffTags {
|
||||
// ModelPixelScaleTag (optional)
|
||||
// Tag = 33550 (830E.H)
|
||||
// Type = DOUBLE
|
||||
// Count = 3
|
||||
const val TAG_MODEL_PIXEL_SCALE = 0x830e
|
||||
|
||||
// ModelTiepointTag (conditional)
|
||||
// Tag = 33922 (8482.H)
|
||||
// Type = DOUBLE
|
||||
// Count = 6*K, K = number of tiepoints
|
||||
const val TAG_MODEL_TIEPOINT = 0x8482
|
||||
|
||||
// ModelTransformationTag (conditional)
|
||||
// Tag = 34264 (85D8.H)
|
||||
// Type = DOUBLE
|
||||
// Count = 16
|
||||
const val TAG_MODEL_TRANSFORMATION = 0x85d8
|
||||
|
||||
// GeoKeyDirectoryTag (mandatory)
|
||||
// Tag = 34735 (87AF.H)
|
||||
// Type = UNSIGNED SHORT
|
||||
// Count = variable, >= 4
|
||||
const val TAG_GEO_KEY_DIRECTORY = 0x87af
|
||||
|
||||
// GeoDoubleParamsTag (optional)
|
||||
// Tag = 34736 (87BO.H)
|
||||
// Type = DOUBLE
|
||||
// Count = variable
|
||||
private const val TAG_GEO_DOUBLE_PARAMS = 0x87b0
|
||||
|
||||
// GeoAsciiParamsTag (optional)
|
||||
// Tag = 34737 (87B1.H)
|
||||
// Type = ASCII
|
||||
// Count = variable
|
||||
private const val TAG_GEO_ASCII_PARAMS = 0x87b1
|
||||
|
||||
val tagNameMap = hashMapOf(
|
||||
TAG_GEO_ASCII_PARAMS to "Geo Ascii Params",
|
||||
TAG_GEO_DOUBLE_PARAMS to "Geo Double Params",
|
||||
TAG_GEO_KEY_DIRECTORY to "Geo Key Directory",
|
||||
TAG_MODEL_PIXEL_SCALE to "Model Pixel Scale",
|
||||
TAG_MODEL_TIEPOINT to "Model Tiepoint",
|
||||
TAG_MODEL_TRANSFORMATION to "Model Transformation",
|
||||
)
|
||||
|
||||
val tags = tagNameMap.keys
|
||||
}
|
|
@ -69,13 +69,13 @@ object MetadataExtractorHelper {
|
|||
- If the ModelPixelScaleTag is included in an IFD, then a ModelTiepointTag SHALL also be included.
|
||||
*/
|
||||
fun ExifDirectoryBase.isGeoTiff(): Boolean {
|
||||
if (!this.containsTag(ExifTags.TAG_GEO_KEY_DIRECTORY)) return false
|
||||
if (!this.containsTag(GeoTiffTags.TAG_GEO_KEY_DIRECTORY)) return false
|
||||
|
||||
val modelTiepoint = this.containsTag(ExifTags.TAG_MODEL_TIEPOINT)
|
||||
val modelTransformation = this.containsTag(ExifTags.TAG_MODEL_TRANSFORMATION)
|
||||
val modelTiepoint = this.containsTag(GeoTiffTags.TAG_MODEL_TIEPOINT)
|
||||
val modelTransformation = this.containsTag(GeoTiffTags.TAG_MODEL_TRANSFORMATION)
|
||||
if (!modelTiepoint && !modelTransformation) return false
|
||||
|
||||
val modelPixelScale = this.containsTag(ExifTags.TAG_MODEL_PIXEL_SCALE)
|
||||
val modelPixelScale = this.containsTag(GeoTiffTags.TAG_MODEL_PIXEL_SCALE)
|
||||
if ((modelTransformation && modelPixelScale) || (modelPixelScale && !modelTiepoint)) return false
|
||||
|
||||
return true
|
||||
|
|
|
@ -26,7 +26,7 @@ object MimeTypes {
|
|||
private const val CR2 = "image/x-canon-cr2"
|
||||
private const val CRW = "image/x-canon-crw"
|
||||
private const val DCR = "image/x-kodak-dcr"
|
||||
private const val DNG = "image/x-adobe-dng"
|
||||
const val DNG = "image/x-adobe-dng"
|
||||
private const val ERF = "image/x-epson-erf"
|
||||
private const val K25 = "image/x-kodak-k25"
|
||||
private const val KDC = "image/x-kodak-kdc"
|
||||
|
|
Loading…
Reference in a new issue