Comments (15)
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>
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.
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.
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.
Excellent. If you get stuck, post the PR as a work-in-progress and I can help you finish it.
from exiftool-vendored.js.
Thanks for the PR! Just released v8.0.0 with support for recursive structs.
from exiftool-vendored.js.
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.
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.
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.
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.
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.
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.
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.
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.
Your PR just adds -struct
to all read tasks. Did you decide that readWithGroups
was not worth it?
from exiftool-vendored.js.
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)
- GPS Tag Write not setting negative HOT 6
- Random error when doing Write HOT 1
- `ExifTool.readRaw` incorrectly has return type `Promise<Tags>` HOT 1
- DefaultExifToolOptions HOT 3
- -g vs -G produces different tag values HOT 2
- incorrect video create date HOT 10
- Stuck forever if perl is missing HOT 2
- Asynchronous operations that weren't stopped HOT 2
- Video `Create Date` with GPS inferred timezone HOT 10
- Wrong timezone offset is parsed from `TimeCreated` tag when using `inferTimezoneFromDatestamps` HOT 4
- Adding values to numericTags does not reflect in Tags type, nor is the function allowed to be properly extended to fix the return value HOT 2
- Regression on timezone extraction from an iPhone photo HOT 3
- "No success message": success regex isn't reliable indicator of "success" HOT 3
- problem with ignoreShebang HOT 3
- GPSLatitude and GPSLongitude differs from GPSPosition HOT 6
- gitlab CI (bullseye-slim) - Error: end() called before task completed HOT 4
- Treat "exiftool-vendored.exe" and "exiftool-vendored.pl" more as optional dependencies HOT 1
- Delete all tags except specified (returns `TypeError`) HOT 5
- inferTimezoneFromDatestamps does not detect UTC/Z/+00:00 timezones HOT 1
- Hang and then timeout on certain files HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from exiftool-vendored.js.