jim-easterbrook / Photini

An easy to use digital photograph metadata (Exif, IPTC, XMP) editing application.
https://photini.readthedocs.io/
GNU General Public License v3.0
164 stars 24 forks source link

Ask for hierarchical tags #279

Closed regexgit closed 1 month ago

regexgit commented 2 months ago

When I was looking for metadata editing software I almost immediately rejected Photini without even trying it because my main selection criterion was hierarchical tags - I have thousands of photos already tagged with this field. Fortunately, my attention was drawn in extremis to other interesting features for which I kept Photini anyway.

But I still miss this function because instead of using Photini for all my metadata I have to use another tool for hierarchical tags.

In addition, hierarchical tags are now commonly used in photo software, it is a shame that Photini is behind on this point.

My main need is to classify animal species using a taxonomy: class/order/suborder/genus/species, for example for a Blue-tailed damselfly: Insecta/Zygoptera/Coenagrionidae/Ishnura/Ishnura elegans.

Without hierarchical tags, you have to assign the Insecta tag, then the Zygoptera tag, then the Coenagrionidae tag, then the Ishnura tag, then the Ishnura elegans tag, which is very annoying and above all a source of errors - the slightest oversight is fatal (i.e. future searches will be erroneous).

With hierarchical tags, all you have to do is select Ishnura elegans and all the parent tags are assigned automatically. It's magical.

The hierarchical structure of tags must be modifiable from within the application, but is generally loaded from a "controlled vocabulary" file.

Apart from this very specific use, hierarchical tags are also very useful for structuring your metadata: Example 1: People/friends/Franck , People/family/Franck. Example 2: Art/painting/nabis/Pierre Bonnard, Art/painting/fauvism/Henri Matisse.

jim-easterbrook commented 2 months ago

Interesting. I assume hierarchical tags are defined in an XMP namespace somewhere. They're not something I've encountered before. For things that don't have them (e.g. Flickr's tags) I suppose a "flattened" version like your examples with '/' characters would be used.

Definitely sounds like something worth having.

jim-easterbrook commented 2 months ago

OK, there's Xmp.lr.hierarchicalSubject and Xmp.mediapro.CatalogSets at least. Finding out how to use them correctly will be fun.

And maybe I'll learn to stop writing "heirarchy" when I mean "hierarchy".

regexgit commented 2 months ago

Yes, it's always Xmp.lr.hierarchicalSubject in my photos, and to ensure compatibility my “photo supreme” software also writes to other fields, here's the output from exiv2 -pa:

Xmp.lr.hierarchicalSubject                   XmpBag      3  Nature|faune|oiseau|passereau|Mésange à longue queue

Iptc.Application2.Keywords                   String      6  oiseau
Iptc.Application2.Keywords                   String      5  faune
Iptc.Application2.Keywords                   String      3  gto
Iptc.Application2.Keywords                   String     24  Mésange à longue queue
Iptc.Application2.Keywords                   String      9  passereau

Xmp.dc.subject                               XmpBag      6  Mésange à longue queue, passereau, oiseau, faune
jim-easterbrook commented 2 months ago

For a user interface I suppose one could have a row of drop down boxes, number of boxes determined by the depth of your deepest previously used tag. The last box would have too many entries, so you might select "fauna" in the first box, then select "Ishnura elegans" in the last box and the others would get the correct values. Or select <new> in any of the boxes to add another tag at that depth (as long as boxes to the left are already set).

regexgit commented 2 months ago

It should work, but there will be a lot of boxes: 5 for birds and 8 for insects: Nature/faune/oiseau/passereau/Mésange à longue queue Nature/faune/insectes/Zygoptera/Coenagrionidae/Ishnura/Ishnura elegans (I've just done a course on dragonflies, and they've forced me to use Latin words !)

I'm afraid the number of boxes won't fit on the line, especially as I don't want to use Photini in full screen mode. But you can also arrange them in columns.

All the software I've used has preferred treeview, so I suppose this implementation is simpler, but I don't know.

Digikam example:

tags_hierarch_digikam

jim-easterbrook commented 2 months ago

That's probably the best. I'm trying not to look at other software so I can think of something new.

jim-easterbrook commented 2 months ago

I'm now thinking of a single line editable box for each hierarchical tag showing the flat view with | separators. Double click on the single line to open a tree view selector with all the user's tags available. The single line boxes would be in rows, with one more row than there are tags so you can always add a new tag.

jim-easterbrook commented 2 months ago

I'm making quite good progress on this. A new "keywords" tab shows the old "flat" keywords and a list of hierarchical keywords read from Xmp.lr.hierarchicalSubject and Xmp.digiKam.TagsList. Context menu on <multiple values> works well. Spell checking is there.

I plan to add buttons to copy tags from flat to hierarchical and vice versa. In the second case I will need a way to declare which 'parent' nodes should be copied to the flat tags - I plan to do this with the yet to be started tree view. This will also be where a user builds up their personal vocabulary.

regexgit commented 2 months ago

I see you've gone all in on this! I can't wait to see the result.

jim-easterbrook commented 2 months ago

I see you've gone all in on this! I can't wait to see the result.

If you're willing to try out the development version you can clone the GitHub repo, switch to the devel branch, and install it with pip.

jim-easterbrook commented 2 months ago

Here's something to whet your appetite. Don't worry about the rubbish data, most of it's loaded from some photos I found online in a complaint about another software's hierarchical keyword handling.

Searching user's hierarchy for ch: Screenshot_20240925_150129

Click on one of the results and the tree view expands to show it, and selects it: Screenshot_20240925_150104

The "set" column shows/changes if the keyword is present in the selected photo(s). The "copy" column sets if the keyword is copied to/from the old flat keywords when the relevant button is clicked. I need better names for these columns.

regexgit commented 2 months ago

With auto completion, it's the ultimate luxury !

jim-easterbrook commented 2 months ago

What auto completion is needed? The search finds a keyword, you then click on a box to add it to or remove it from your photos.

jim-easterbrook commented 2 months ago

One idea: when typing into a hierarchical keyword field on the normal tab (i.e. not the "edit keyword hierarchy" dialog) I could use the same popup if what you've typed matches a known keyword.

For example, start typing Ishn and all the species pop up for you to choose the complete hierarchy of the one you want.

regexgit commented 2 months ago

What auto completion is needed?

You type “ch” and find “Chateau gautier”, which is what we call autocompletion. It may seem obvious to you, but in the tools I use, it's not that common.

jim-easterbrook commented 2 months ago

Also works (for Château-Gontier) if you type "gon". To be clear, is what I've implemented sufficient?

regexgit commented 2 months ago

Obviously!

You didn't understand the original meaning of my comment, which wasn't at all a request for something extra, but a compliment on what you've implemented: in my usual tools, autocompletion doesn't exist (or in a rudimentary form), so I was just expressing my satisfaction at seeing this feature appear, that's all.

jim-easterbrook commented 2 months ago

I've found a QCompleter class in Qt that does just what's needed, although it took a bit of effort to present it with a "list view" of the hierarchy's full names (i.e. with all ancestors and | separators). It's all coming together quite nicely now.

jim-easterbrook commented 2 months ago

First go at documenting the hierarchical keywords stuff. https://photini.readthedocs.io/en/devel/manual/keywords.html

regexgit commented 1 month ago

Sounds great. I don't see anything to add.

jim-easterbrook commented 1 month ago

Now available in release 2024.10.0

regexgit commented 1 month ago

It works well, I just have one comment on the buttons:

Copy to keywords: if I need to copy the keywords for software compatibility reasons, I have to remember to click on this button for all the photos, boring, it should rather be an option in ’Preferences”.

Copy to hierarchy: In the documentation see the last 2 screenshots: after “Copy to hierarchy” the 2 lines are replaced by a single one because:

In this case it has copied both “places|France” and “places|France|Château-Gontier”. Only the latter is needed so the former can be deleted.

This is not the observed behavior, on the contrary my single line is replaced by 3 lines.

Example: declaration in the tree, my last 3 levels can be copied: image-20241023011309730

Set of keyword "Buse variable": image-20241023011456026

"Copy to keywords": image-20241023011642989

“Copy to hierarchy”: image-20241023011708377

jim-easterbrook commented 1 month ago

Copy to keywords: when would this happen? Doing it every time a picture is loaded breaks Photini's principle of not modifying anything unless the user makes a change. Doing it when keywords are being edited is risky. Currently it does the wrong thing if you select multiple images with different hierarchical keywords.

Copy to hierarchy: I think you've misunderstood. It creates three hierarchical keywords, two of which aren't needed so you could delete them.

regexgit commented 1 month ago

Some photo software programs don't recognize hierarchical tags and will only read “Xmp.dc.subject”, so you need to copy the hierarchical tags into this field for all photos. In fact, it's common practice for Digital Asset Management tools to write to several fields at once. Otherwise, I can't think of any other case where the “copy keywords” button would be useful for one photo only and not for another ?

And what's the point of creating several hierarchies if you then have to delete them ?

So for my personal use, these 2 buttons are useless, but it doesn't matter, the rest suits me perfectly.

jim-easterbrook commented 1 month ago

Photini, of course, writes several fields for a lot of its data. However, there isn't a simple one-to-one mapping between hierarchical and flat keywords (hence my "copyable" setting for each tag in your personal data model).

And what's the point of creating several hierarchies if you then have to delete them ?

No point, it's just how it currently works as it was quick and easy to do. I'm working on fixing that.

jim-easterbrook commented 1 month ago

I think your idea of auto-syncing the hierarchical and flat keywords might be doable. You may have already noticed Photini's merging of text from different Exif/IPTC/XMP fields with a // delimiter to show it's a merged value. This doesn't change the data in the file until the user saves it.

If I rename the 'copyable' setting to 'sync' and make it False unless explicitly set by the user then it should be safe for those who aren't interested in one or other type of keywords. I'll give it some more thought.

jim-easterbrook commented 1 month ago

Here's the current development version with the two commits mentioned above that should solve some of your problems. Photini-2024.10.0.post2.zip

jim-easterbrook commented 1 month ago

Here's a version with full syncing between flat and hierarchical keywords. Photini-2024.10.0.post5.zip

regexgit commented 1 month ago

Thanks, that's exactly what I wanted.

The user should bear in mind that this synchronization can sometimes fail when there is ambiguity over terms, for example: Hierarchical: person/friends/Tom; person/family/Tom Flat: Tom

In the hierarchical => flat direction, we simply lose information, but in the flat => hierarchical direction, we have 2 “Toms” and we'll have to delete one.

No big deal, you just need to know it

jim-easterbrook commented 1 month ago

That's exactly the problem I'm just starting to work on. In some cases the ambiguity may be resolvable with other flat keywords, e.g. places|USA|Newport and places|UK|Newport can be disambiguated if UK is in the flat keywords and USA isn't. In other cases I'll put a warning message and the user can then manually add one of the hierarchical keywords. This might add USA or UK to the flat keywords, resolving the ambiguity.

jim-easterbrook commented 1 month ago

Here's the latest iteration to try out. Photini-2024.10.0.post15.zip

jim-easterbrook commented 1 month ago

One thing I've been thinking about is dropping the italics for non-copyable words and prepending an asterisk to copyable words. This would allow the user to set the copyability of a new hierarchical keyword without ever opening the tree view.

regexgit commented 1 month ago

I'm not sure, when I add a keyword in the hierarchical field it's almost always a terminal node in an existing category and in that case it must be copyable by default (currently it isn't), that's enough for me.

jim-easterbrook commented 1 month ago

I've turned off the "last node copyable by default" as with the auto-syncing it would cause problems for anyone who wants to keep their flat and hierarchical keywords separate. (I know that sounds odd, but there will be someone.) Allowing an asterisk at the time of typing it in should be almost as easy.

jim-easterbrook commented 1 month ago

Documentation of the development version. https://photini.readthedocs.io/en/devel/manual/keywords.html