Code Monkey home page Code Monkey logo

Comments (15)

Circuit8 avatar Circuit8 commented on May 18, 2024 1

So the command for writing I think would be something along the lines of this:

exiftool -RegistryID="[
  {RegItemId=Number1,RegOrgId=TestName1}, 
  {RegItemId=Number2,RegOrgId=TestName2},
  {RegItemId=Number3,RegOrgId=TestName3}
]" black.jpg

This sets the RegistryID field, with the RegItemId and RegOrgId fields. I believe that each struct field defines the permitted list of key names on the exiftool site, although probably best to just let exiftool handle that when writing and return any errors from it.

For reading we'd need something like exiftool -struct image.jpg which then returns the data in a parsable way I think.

I've attached an image with some struct data saved on it. Below is the snippet of how the XMP is stored in the image:

 <rdf:Description rdf:about=''
  xmlns:Iptc4xmpExt='http://iptc.org/std/Iptc4xmpExt/2008-02-29/'>
  <Iptc4xmpExt:RegistryId>
   <rdf:Bag>
    <rdf:li rdf:parseType='Resource'>
     <Iptc4xmpExt:RegItemId>Number1</Iptc4xmpExt:RegItemId>
     <Iptc4xmpExt:RegOrgId>TestName1</Iptc4xmpExt:RegOrgId>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <Iptc4xmpExt:RegItemId>Number2</Iptc4xmpExt:RegItemId>
     <Iptc4xmpExt:RegOrgId>TestName2</Iptc4xmpExt:RegOrgId>
    </rdf:li>
    <rdf:li rdf:parseType='Resource'>
     <Iptc4xmpExt:RegItemId>Number3</Iptc4xmpExt:RegItemId>
     <Iptc4xmpExt:RegOrgId>TestName3</Iptc4xmpExt:RegOrgId>
    </rdf:li>
   </rdf:Bag>
  </Iptc4xmpExt:RegistryId>
 </rdf:Description>

black

Running exiftool -struct black.jpg returns this:

Registry ID: [{RegItemId=Number1,RegOrgId=TestName1},{RegItemId=Number2,RegOrgId=TestName2},{RegItemId=Number3,RegOrgId=TestName3}]

Let me know if you need anything else!

from exiftool-vendored.js.

Circuit8 avatar Circuit8 commented on May 18, 2024 1

Actually the more I think about it the more I like your original solution ExifTool.readWithGroups(), just group everything by its namespace. Nice and clean, and gives you everything you need to know, and doesn't change if there's collisions or not, the field will just appear in more than one category.

from exiftool-vendored.js.

Circuit8 avatar Circuit8 commented on May 18, 2024 1

Hey I've found some time to finally get my head around Typescript and have a go at this. Hopefully I'll have a PR for you in the next few days

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024 1

Excellent. If you get stuck, post the PR as a work-in-progress and I can help you finish it.

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024 1

Thanks for the PR! Just released v8.0.0 with support for recursive structs.

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024

This sounds like a great feature to add.

Is it as simple as adding -struct -xmp:all? Do you have an example image with XMP data I can play with?

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024

OK, so, here's the JSON I'd be playing with:

$ exiftool -f -struct -xmp:all -all -j ~/Desktop/50146712-537f6880-02ac-11e9-8c6b-a7cd3c21e677.jpg

[{
  "SourceFile": "/home/mrm/Desktop/50146712-537f6880-02ac-11e9-8c6b-a7cd3c21e677.jpg",
  "XMPToolkit": "Image::ExifTool 10.86",
  "RegistryID": [{
    "RegItemId": "Number1",
    "RegOrgId": "TestName1"
  },{
    "RegItemId": "Number2",
    "RegOrgId": "TestName2"
  },{
    "RegItemId": "Number3",
    "RegOrgId": "TestName3"
  }],
  "Format": "image/jpeg",
  "ColorClass": "0 (None)",
  "PMVersion": "PM5",
  "Prefs": "Tagged:0, ColorClass:0, Rating:0, FrameNum:-00001",
  "Tagged": "No",
  "ColorMode": "RGB",
  "DateCreated": "2017:02:20 18:06:40",
  "ICCProfileName": "sRGB IEC61966-2.1",
  "CreateDate": "2017:02:20 18:06:40",
  "CreatorTool": "Adobe Photoshop CC 2015.5 (Macintosh)",
  "MetadataDate": "2017:02:20 18:06:40Z",
  "Rating": 0,
  "DocumentID": "adobe:docid:photoshop:c0d85d3a-3825-117a-942d-cd1eb4adf38f",
  "History": [{
    "Action": "created",
    "InstanceID": "xmp.iid:6c2b9b71-8d72-417d-a9b9-d418758f0a60",
    "SoftwareAgent": "Adobe Photoshop CC 2015.5 (Macintosh)",
    "When": "2017:02:20 18:06:40Z"
  },{
    "Action": "saved",
    "Changed": "/",
    "InstanceID": "xmp.iid:21668b75-ca33-4d35-8765-888fec3e203f",
    "SoftwareAgent": "Adobe Photoshop CC 2015.5 (Macintosh)",
    "When": "2017:02:20 18:06:40Z"
  }],
  "InstanceID": "xmp.iid:21668b75-ca33-4d35-8765-888fec3e203f",
  "OriginalDocumentID": "xmp.did:6c2b9b71-8d72-417d-a9b9-d418758f0a60",
  "ExifToolVersion": 10.80,
...

Without the tag group name, it seems like it'd be likely to have field collisions. I feel like it might be better to use the group names:

$ exiftool -g -struct -xmp:all -all -j ~/Desktop/50146712-537f6880-02ac-11e9-8c6b-a7cd3c21e677.jpg

[{
  "SourceFile": "/home/mrm/Desktop/50146712-537f6880-02ac-11e9-8c6b-a7cd3c21e677.jpg",
  "ExifTool": {
    "ExifToolVersion": 10.80
  },
  "File": {
    "FileName": "50146712-537f6880-02ac-11e9-8c6b-a7cd3c21e677.jpg",
    "Directory": "/home/mrm/Desktop",
    "FileSize": "154 kB",
    "FileModifyDate": "2018:12:18 22:21:30-08:00",
    "FileAccessDate": "2018:12:18 22:21:58-08:00",
    "FileInodeChangeDate": "2018:12:18 22:21:36-08:00",
    "FilePermissions": "rw-rw-r--",
    "FileType": "JPEG",
    "FileTypeExtension": "jpg",
    "MIMEType": "image/jpeg",
    "ExifByteOrder": "Big-endian (Motorola, MM)",
    "CurrentIPTCDigest": "28b63cab1b8d021d9234e52c1d24e69b",
    "ImageWidth": 2000,
    "ImageHeight": 1079,
    "EncodingProcess": "Baseline DCT, Huffman coding",
    "BitsPerSample": 8,
    "ColorComponents": 3,
    "YCbCrSubSampling": "YCbCr4:4:4 (1 1)"
  },
  "EXIF": {
    "Orientation": "Horizontal (normal)",
    "XResolution": 300,
    "YResolution": 300,
    "ResolutionUnit": "inches",
    "Software": "Adobe Photoshop CC 2015.5 (Macintosh)",
    "ModifyDate": "2017:02:20 18:06:40",
    "ColorSpace": "sRGB",
    "ExifImageWidth": 2000,
    "ExifImageHeight": 1079,
    "Compression": "JPEG (old-style)",
    "ThumbnailOffset": 322,
    "ThumbnailLength": 802,
    "ThumbnailImage": "(Binary data 802 bytes, use -b option to extract)"
  },
  "IPTC": {
    "ApplicationRecordVersion": 3,
    "DateCreated": "2017:02:20",
    "TimeCreated": "18:06:40+00:00",
    "Prefs": "Tagged:0, ColorClass:0, Rating:0, FrameNum:-00001"
  },
  "Photoshop": {
    "IPTCDigest": "00000000000000000000000000000000",
    "XResolution": 300,
    "DisplayedUnitsX": "inches",
    "YResolution": 300,
    "DisplayedUnitsY": "inches",
    "PrintStyle": "Centered",
    "PrintPosition": "0 0",
    "PrintScale": 1,
    "GlobalAngle": 90,
    "GlobalAltitude": 30,
    "URL_List": [],
    "SlicesGroupName": "Untitled-1",
    "NumSlices": 1,
    "PixelAspectRatio": 1,
    "PhotoshopThumbnail": "(Binary data 802 bytes, use -b option to extract)",
    "HasRealMergedData": "Yes",
    "WriterName": "Adobe Photoshop",
    "ReaderName": "Adobe Photoshop CC 2015.5",
    "PhotoshopQuality": 12,
    "PhotoshopFormat": "Standard",
    "ProgressiveScans": "3 Scans"
  },
  "XMP": {
    "XMPToolkit": "Image::ExifTool 10.86",
    "RegistryID": [{
      "RegItemId": "Number1",
      "RegOrgId": "TestName1"
    },{
      "RegItemId": "Number2",
      "RegOrgId": "TestName2"
    },{
      "RegItemId": "Number3",
      "RegOrgId": "TestName3"
    }],
    "Format": "image/jpeg",
    "ColorClass": "0 (None)",
    "PMVersion": "PM5",
    "Prefs": "Tagged:0, ColorClass:0, Rating:0, FrameNum:-00001",
    "Tagged": "No",
    "ColorMode": "RGB",
    "DateCreated": "2017:02:20 18:06:40",
    "ICCProfileName": "sRGB IEC61966-2.1",
    "CreateDate": "2017:02:20 18:06:40",
    "CreatorTool": "Adobe Photoshop CC 2015.5 (Macintosh)",
    "MetadataDate": "2017:02:20 18:06:40Z",
    "ModifyDate": "2017:02:20 18:06:40Z",
    "Rating": 0,
    "DocumentID": "adobe:docid:photoshop:c0d85d3a-3825-117a-942d-cd1eb4adf38f",
    "History": [{
      "Action": "created",
      "InstanceID": "xmp.iid:6c2b9b71-8d72-417d-a9b9-d418758f0a60",
      "SoftwareAgent": "Adobe Photoshop CC 2015.5 (Macintosh)",
      "When": "2017:02:20 18:06:40Z"
    },{
      "Action": "saved",
      "Changed": "/",
      "InstanceID": "xmp.iid:21668b75-ca33-4d35-8765-888fec3e203f",
      "SoftwareAgent": "Adobe Photoshop CC 2015.5 (Macintosh)",
      "When": "2017:02:20 18:06:40Z"
    }],
    "InstanceID": "xmp.iid:21668b75-ca33-4d35-8765-888fec3e203f",
    "OriginalDocumentID": "xmp.did:6c2b9b71-8d72-417d-a9b9-d418758f0a60"
  },
  "ICC_Profile": {
    "ProfileCMMType": "Linotronic",
    "ProfileVersion": "2.1.0",
    "ProfileClass": "Display Device Profile",
    "ColorSpaceData": "RGB ",
    "ProfileConnectionSpace": "XYZ ",
    "ProfileDateTime": "1998:02:09 06:49:00",
...

What do you think? Should I add a new ExifTool.readWithGroups() (or groupedRead) method, that returns this sort of nested structure?

Without using the nested groups, there are a lot of fields with colliding names, and it'd be impossible to discern what group provided the value.

from exiftool-vendored.js.

Circuit8 avatar Circuit8 commented on May 18, 2024

That does sound like a good idea. So the API could be readWithGroups or just read, or we could have it as an optional configuration paramter to read like read({ withGroups: true }).

I don't understand why this is a new issue though, wasn't there always risk of group namespace collision?

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024

I don't understand why this is a new issue though, wasn't there always risk of group namespace collision?

You're right, and in mktags I actually had to remove tags that collide, but those tags seemed to have the same semantic value.

Think FlashFired: I'd be surprised if the messing of that tag changed based on what group you found it in.

Something generic like History, though, seems like it should be quarantined to its own group to disambiguate.

Does that make sense?

from exiftool-vendored.js.

Circuit8 avatar Circuit8 commented on May 18, 2024

Yeah I think so.

One idea is we could use the call to exiftool to get the grouped data like you suggested, but then rather than returning that to the user, we collate it all into one object. If there are any collisions with the same key in different namespaces we prepend the namespace into the results, e.g:

{
  "Non-Clashing-Field": "some stuff",
  "IPTC:History": "history from iptc",
  "xmp-dc:History": "history from xmp",
}

The benefit of this is that its the same format as what exiftool expects if you're writing to a specific subgroup.

What do you reckon?

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024

I think I've gotten into trouble when I've done this in the past with APIs in an effort to be "nice".

What happens if the tag is colliding in one file and not in another? You'd have to look for History in two places.

I like the idea that the colon-separated tags are what ExifTool expects, so we aren't inventing Yet Another API.

This would make the tags objects larger, but what do you think about doing both: put all non-clashing fields into the groupless top level, and prefix every tag with their group name?

from exiftool-vendored.js.

Circuit8 avatar Circuit8 commented on May 18, 2024

I've managed to get a PR together #43. Let me know what you think.

BTW I'm starting to see why Typescript could be useful, I was quite anti TS before but after doing some reading I'm beginning to see the benefits. Are you using it in your other projects and do you feel the safety gains are worth the extra overhead?

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024

I've lived with very large C, C++, java, ruby, python, and scala projects, and find that the compiler is definitely your friend in all cases. The large ruby and python projects I've worked on were extremely hard to make confident changes in. I wouldn't develop in javascript directly if I had the choice.

from exiftool-vendored.js.

mceachen avatar mceachen commented on May 18, 2024

Your PR just adds -struct to all read tasks. Did you decide that readWithGroups was not worth it?

from exiftool-vendored.js.

Circuit8 avatar Circuit8 commented on May 18, 2024

I think at some point readWithGroups would be useful, perhaps as a separate option, but it actually works just fine with -struct at the moment in the same vein as how it worked before.

Cool I might look into using TS a bit more myself.

Do you have any ideas about what we can do to get structs in added to Tags.ts with mktags?

from exiftool-vendored.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.