Skip to content

Commit

Permalink
Write MWG-rs face tags (#20)
Browse files Browse the repository at this point in the history
* Update Kotlin & promote to v1.0.0

* Added test data

* Added TYPE_AREA namespace

* One step further

* One step further

* XMPPathParser.kt: Fixed comment style

* Implemented XMPMeta.setFaces()

* MWG-rs region type must be "Face"

* Renamed field
  • Loading branch information
StefanOltmann authored Jan 12, 2024
1 parent bf2e234 commit e5bca0e
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 45 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# XMP Core for Kotlin Multiplatform

[![Kotlin](https://img.shields.io/badge/kotlin-1.9.21-blue.svg?logo=kotlin)](httpw://kotlinlang.org)
[![Kotlin](https://img.shields.io/badge/kotlin-1.9.22-blue.svg?logo=kotlin)](httpw://kotlinlang.org)
![JVM](https://img.shields.io/badge/-JVM-gray.svg?style=flat)
![Android](https://img.shields.io/badge/-Android-gray.svg?style=flat)
![macOS](https://img.shields.io/badge/-macOS-gray.svg?style=flat)
Expand All @@ -17,7 +17,7 @@ It's part of [Ashampoo Photos](https://ashampoo.com/photos).
## Installation

```
implementation("com.ashampoo:xmpcore:0.3")
implementation("com.ashampoo:xmpcore:1.0.0")
```

## How to use
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl

plugins {
kotlin("multiplatform") version "1.9.21"
kotlin("multiplatform") version "1.9.22"
id("com.android.library") version "8.0.2"
id("maven-publish")
id("signing")
Expand Down
4 changes: 4 additions & 0 deletions src/commonMain/kotlin/com/ashampoo/xmp/XMPConst.kt
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ object XMPConst {
*/
const val TYPE_DIMENSIONS: String = "http://ns.adobe.com/xap/1.0/sType/Dimensions#"

const val TYPE_AREA: String = "http://ns.adobe.com/xmp/sType/Area#"

const val TYPE_TEXT: String = "http://ns.adobe.com/xap/1.0/t/"

const val TYPE_PAGED_FILE: String = "http://ns.adobe.com/xap/1.0/t/pg/"
Expand Down Expand Up @@ -294,4 +296,6 @@ object XMPConst {

const val XMP_IPTC_EXT_PERSON_IN_IMAGE: String = "PersonInImage"

const val XMP_MWG_RS_TYPE_FACE: String = "Face"

}
124 changes: 116 additions & 8 deletions src/commonMain/kotlin/com/ashampoo/xmp/XMPMeta.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package com.ashampoo.xmp

import com.ashampoo.xmp.Utils.normalizeLangValue
import com.ashampoo.xmp.XMPConst.NS_MWG_RS
import com.ashampoo.xmp.XMPNodeUtils.appendLangItem
import com.ashampoo.xmp.XMPNodeUtils.chooseLocalizedText
import com.ashampoo.xmp.XMPNodeUtils.deleteNode
Expand Down Expand Up @@ -1655,7 +1656,7 @@ class XMPMeta {
val regionType = getPropertyString(XMPConst.NS_MWG_RS, "$prefix:Type")

/* We only want faces. */
if (regionType != "Face")
if (regionType != XMPConst.XMP_MWG_RS_TYPE_FACE)
continue

val name = getPropertyString(XMPConst.NS_MWG_RS, "$prefix:Name")
Expand All @@ -1675,13 +1676,120 @@ class XMPMeta {
return faces
}

// fun setFaces(faces: Map<String, XMPRegionArea>) {
//
// /* Delete existing entries, if any */
// deleteProperty(NS_MWG_RS, "Regions")
//
// // TODO Write faces
// }
fun setFaces(
faces: Map<String, XMPRegionArea>,
widthPx: Int,
heightPx: Int
) {

/* Delete existing entries, if any */
deleteProperty(NS_MWG_RS, "Regions")

if (faces.isNotEmpty()) {

setStructField(
NS_MWG_RS, "Regions/mwg-rs:AppliedToDimensions",
XMPConst.TYPE_DIMENSIONS, "w",
widthPx.toString()
)

setStructField(
NS_MWG_RS, "Regions/mwg-rs:AppliedToDimensions",
XMPConst.TYPE_DIMENSIONS, "h",
heightPx.toString()
)

setStructField(
NS_MWG_RS, "Regions/mwg-rs:AppliedToDimensions",
XMPConst.TYPE_DIMENSIONS, "unit", "pixel"
)

setStructField(
NS_MWG_RS, "Regions", NS_MWG_RS, "RegionList",
null, arrayOptions
)

faces.onEachIndexed { index, face ->

val oneBasedIndex = index + 1

val structNameItem = "Regions/mwg-rs:RegionList[$oneBasedIndex]"
val structNameArea = "$structNameItem/mwg-rs:Area"

insertArrayItem(
schemaNS = NS_MWG_RS,
arrayName = "Regions/mwg-rs:RegionList",
itemIndex = oneBasedIndex,
itemValue = "",
options = PropertyOptions().setStruct(true)
)

setStructField(
NS_MWG_RS,
structNameItem,
XMPConst.NS_MWG_RS,
"Type",
XMPConst.XMP_MWG_RS_TYPE_FACE
)

setStructField(
NS_MWG_RS,
structNameItem,
XMPConst.NS_MWG_RS,
"Name",
face.key
)

setStructField(
NS_MWG_RS,
structNameArea,
XMPConst.TYPE_AREA,
"x",
face.value.xPos.toString()
)

setStructField(
NS_MWG_RS,
structNameArea,
XMPConst.TYPE_AREA,
"x",
face.value.xPos.toString()
)

setStructField(
NS_MWG_RS,
structNameArea,
XMPConst.TYPE_AREA,
"y",
face.value.yPos.toString()
)

setStructField(
NS_MWG_RS,
structNameArea,
XMPConst.TYPE_AREA,
"w",
face.value.width.toString()
)

setStructField(
NS_MWG_RS,
structNameArea,
XMPConst.TYPE_AREA,
"h",
face.value.height.toString()
)

setStructField(
NS_MWG_RS,
structNameArea,
XMPConst.TYPE_AREA,
"unit",
"normalized"
)
}
}
}

fun getPersonsInImage(): Set<String> {

Expand Down
4 changes: 2 additions & 2 deletions src/commonMain/kotlin/com/ashampoo/xmp/XMPNodeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ object XMPNodeUtils {

!parent.isImplicit ->
throw XMPException(
"Named children only allowed for schemas and structs", XMPError.BADXPATH
"Named children only allowed for schemas and structs: $childName", XMPError.BADXPATH
)

parent.options.isArray() ->
throw XMPException("Named children not allowed for arrays", XMPError.BADXPATH)
throw XMPException("Named children not allowed for arrays: $childName", XMPError.BADXPATH)

createNodes ->
parent.options.setStruct(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ object XMPSchemaRegistry {
registerNamespace(XMPConst.TYPE_IMAGE, "xmpGImg")
registerNamespace(XMPConst.TYPE_FONT, "stFnt")
registerNamespace(XMPConst.TYPE_DIMENSIONS, "stDim")
registerNamespace(XMPConst.TYPE_AREA, "stArea")
registerNamespace(XMPConst.TYPE_RESOURCE_EVENT, "stEvt")
registerNamespace(XMPConst.TYPE_RESOURCE_REF, "stRef")
registerNamespace(XMPConst.TYPE_ST_VERSION, "stVer")
Expand Down
Loading

0 comments on commit e5bca0e

Please sign in to comment.