[Update and big fat warning]: apparently, renaming or moving files does mess with the tags the image already has. A way around this, and maybe a generally good idea (use your own judgement on that one), is to make digiKam save the tags as metadata into the picture files themselves. On the con side, tagging your pictures will actually modify the files (maybe you don’t want that), but on the pro side, the tags will travel along with the files, no matter what name or location they have (even to other computers, which may or may not be what you want).
[Update #2]: apparently the metadata approach doesn’t work either. It seems that each time a tag is assigned, the metadata is immediately saved (which is great), but only the tags digiKam is aware of at that moment. Also, digiKam is not immediately aware of the tag metadata of the pics it’s showing (you have to tell him so, I think). Let’s say you tag a pic as “A”. Metadata for “A” is saved. OK. Now, you change the name of the file, and digiKam loses track of it. You rename back, and digiKam thinks the picture has no tag (the metadata is obviously still there, inside the file, but digiKam doesn’t read it until you tell it to). Now, you assign tag “B” to the picture, expecting the file to end up with both tags: A and B. Tough luck. The split second you tag the file with “B”, it is written to the metadata (OK), but only tag B is written (the only one digiKam is aware of at that moment), so tag “A” is lost. In two words: the following post is full of crap. If a third word is allowed, let me say that digiKam is too.
First off, let me admit that my problem might have a simple solution. Maybe my goal is much simpler to achieve than I think. But what I am doing seems fairly common to me, and a pain-free recipe to do it escapes me.
I use digiKam to manage my photo collection. A very handy (and basic) function of digiKam is to tag photos. I tag photos with three criteria: where it was taken (e.g. “Donostia”), the event it can be framed within (e.g. “Wedding of A and B”), and a tag per person that appears in it (e.g. “John Smith”, “Jane Doe” and “Janet Johnson”). It involves some work, but afterwards I can really easily find say, all pictures in which John Smith and Jane Doe appear together, in any place but Donostia. Why I would want to do that is anyone’s guess, but that’s offtopic.
Every time I have a batch of photos (say, a wedding or some holidays), I sit down in front of my computer, and tag evey one of them. Tagging by event is a breeze (99.9% of the time, the whole batch of pics belongs to the same event), and tagging by location is also simple (each pic has a single location, and many, if not all, share that location). However, tagging by person is a bit trickier. Each photo can have many (or no) people appearing on it, plus it takes a bit of attention to spot all people appearing.
When tagging by people, two approaches can be taken:
- Parse photo by photo, tagging each one once per person appearing on it. Don’t move to the next photo until tags for eveyone appearing on current one have been asigned.
- Parse whole batch, once per person. You pick a person, select all pics where she appears, then you tag all of them simultaneously. Repeat for each person.
I have found that, for large amounts of pictures, the second approach is fairly superior. However, it is not problem-free. Firstly, multiple selection is only possible in a grid view. That is, pictures are presented as thumbnails, aligned in columns and rows. Even in the largest possible size for such pictures, often times there are many photos that are too small to spot all people in them. Secondly, having selected some dozens of pictures out of some hundreds, and mistakenly unselecting them by clicking where you shouldn’t, or failing to hold the Ctrl key when clicking (or whatever error whose probability to happen increases with the amount of pictures to tag) is just painful.
Fairy tale solution
I realized a hybrid method would be advantageous, but that’s where the problem comes: I find no simple way to accomplish it. I would like to be able to do the following comfortably: inspect the photos one by one, tagging each one in which person A appears. When all are tagged, repeat for person B, and so on. Right now this approach will take longer than either approaches above, because it borrows the worse characteristics from both (one-by-one tagging of method 1, scanning all the photos repeatedly, once per person, from method 2). The reason for that is that asigning a single tag to a single photo is cumbersome. You right-click on the photo, then select “Assign Tag” from the menu that appears, then choose a tag from the drop-down menu (and submenus if case be).
There is no shortcut that one can assign to some tag, or, even better, a single-key shortcut for “assign to this photo the last tag I have assigned to the previous one”. If there was, my hybrid approach would be really fast: take person A, appearing in picture 1. Tag pic 1 with “A”. Then go picture by picture (a single hit of the space bar), either ignoring the pics where person “A” does not appear, or pressing the “apply last tag” shortcut (a single keystroke) where she does.
Of the tools that digiKam offers, which one can modify a photo in a way that the contents are not touched, yet we can group them afterwards based on that change? Easy: rename (F2 key). When you press F2, a rename dialog appears, with a field where you can enter the new name for the currently selected pic. The good thing is the field is already filled with the current name of the photo. So, if you want to rename a photo to, say, the same name but with a trailing dot, all you have to do is press the sequence: F2 + . + Enter.
Now, how on Earth would the renaming help? Well, we could use the above “trick” to quickly rename all pictures in which person A appears, making all of them have the same name, but with a trailing dot added. Then, we could Alt-Tab to a terminal, cd to the dir where the photos reside, and execute the following (zsh syntax, translate to your favorite shell):
% for file in *.; mv $file totag/`echo $file | sed ‘s/.$//’`
That will put all files ending in a dot inside a subfolder called “totag”, renaming them back to their original name (chopping off the last character, which would be the dot). Don’t forget the fact that these files happen to be all in which person A appears.
Recall as well that digiKam keeps track of the tags applied to each photo by its md5sum (OK, I made that up, but it must be true), so moving files around and/or renaming them (both things are one and the same, actually) doesn’t mess with the tags. (see warning at the top of this post).
So, once all pics with person A reside in folder “totag”, we can Alt-Tab back to digiKam, go to that folder, select all pics, and tag them all at once. After that, Alt-Tab to the terminal, and execute:
The real beauty of using a shell for that (even with the apparently complicated command with the for loop above), is that you can reuse the commands trivially. For person B, once all relevant photos have been renamed with a dot, Alt-Tab to the terminal, hit the Up arrow twice, then Enter, and you will move and rename all files again in just three keystrokes (two of them being the same key hit twice). Alt-Tab to digiKam, tag all pics in the “totag” dir. Alt-Tab to the terminal, Up+Up+Enter (which now executes the mv), and you have the files in the main dir again.
Yeah, I bet right now you are considering whether my idea of what is “simple” or “comfortable” is seriously off. I’d still vote for the “Reapply last tag” shortcut in digiKam. It would make a three-keystroke step (F2+.+Enter, to rename) a single keystroke one (reapply last tag with shortcut), plus would make the steps involving the terminal unnecessary. But reality is a bitch, and we don’t have such a shortcut. I could either just rant about it on my blog, or go ahead and find a solution myself. I chose to do both :^)Tags: about me, digikam, en, FLOSS, howto, logic, optimization, photos, software, zsh
3 Comments »