Ansel erft van Darktable de ruggengraat van zijn database: de niet-destructieve bewerkingsgeschiedenissen worden per foto opgeslagen in een SQLite-database, samen met metadata en andere door de gebruiker gedefinieerde gegevens. De database bewust maken van nieuwe foto’s gebeurt door foto’s te „importeren" van een schijf of een geheugenkaart. Daar komt de importtool in beeld.
Helaas is de Darktable-importeur nog zoiets dat rond 2020 werd verminkt en omgevormd tot iets diep verontrustends, want het is een bestandsverkenner die op geen enkele eerder bekende bestandsverkenner lijkt, en die erin slaagt om basisfuncties te missen (zoals Ctrl+F of EXIF-voorbeeld) terwijl hij tegelijk overladen is met nutteloze (zie hieronder). Hier verliezen we menig toekomstig gebruiker, en het is nog maar stap 0 van de workflow. Wat een geweldig visitekaartje van wat een „workflow-app" kan doen!
Een designbeoordeling van waar ontwerp door commissie je brengt
Darktable heeft dus de importknoppen op een zijbalkwidget. Er zijn er 3 als je een camera via USB hebt aangesloten, anders 2:

Vele forumberichten zijn verspild aan het keer op keer uitleggen wat het verschil was tussen toevoegen aan bibliotheek en importeren en kopiëren (importeren betekent eigenlijk toevoegen aan bibliotheek). Het is ook het vermelden waard dat de knop camera aankoppelen niets meer doet dan wat elk systeembreed PTP - of MTP -stuurprogramma voor je doet: de interne SD-kaart aankoppelen als externe USB-opslag, via de USB-poort van de camera. Op Windows vereist dit het installeren van een aangepast USB-stuurprogramma dat verhindert dat je camera met de rest van het besturingssysteem werkt. Op Linux moet je, afhankelijk van of je besturingssysteem „automatisch aankoppelen" ingeschakeld heeft, de camera mogelijk eerst afkoppelen van de bestandsverkenner van je bureaublad, anders vergrendelt het de verbinding. Op alle besturingssystemen vereist dit dat er de hele tijd op de achtergrond naar nieuwe apparaten wordt geluisterd, zodat de applicatie kan reageren op hot-plugging, of je de functie nu gaat gebruiken of niet.
En dan zijn er nog de parameters. Sinds 2022 is het Darktable-team smoorverliefd geworden op die inklapbare laden die de opgeblazenheid onder nog meer opgeblazenheid verbergen. En de opgeblazenheid die je daarin vindt doet niets meer dan Ctrl+A (alle foto’s selecteren), en dan 0 of 1 (om een initiële beoordeling van 0 of 1 ster toe te kennen) of de metadata-info (in batch) invullen in de gelijknamige module, die in de lichttafel-GUI staat of je dat nu leuk vindt of niet, en presets ondersteunt voor het geval je altijd dezelfde metadata hergebruikt. Waarom het toevoegen van deze parameters daar überhaupt een vereiste was gaat mijn begrip te boven. Iemand, ergens, bespaart waarschijnlijk 0,5 s per importsessie, die de rest van de wereld verliest met meer scrollen in de hoogte.
Dus, aangenomen dat je de verschillen tussen al die opties hebt begrepen, klik je nu op importeren en kopiëren, wat waarschijnlijk het meest gebruikte is aangezien elke fotograaf de SD-kaarten naar een meer permanente opslag moet legen. En dan…

Dit is in feite toegeven dat het ontwerp zo verschrikkelijk is dat het grenst aan onbruikbaar zonder de documentatie te lezen. Maar wacht, wat zijn we ook alweer aan het doen? We zijn foto’s aan het kopiëren. We zijn foto’s aan het kopiëren? Heb je dan je examen fotokopiëren gehaald en je diploma fotokopiëren behaald? Zo niet, dan zou je dat moeten doen. Pas op, ze maken er in een toekomstige versie misschien een quiz van en schakelen de functie uit als je zakt.
Dus klik je op die onheilspellende knop die zegt dat je de volledige verantwoordelijkheid op je neemt voor welke schade er ook mag ontstaan door het kopiëren van foto’s. Of je doet het niet, aangezien het er nogal eng uitziet. Maar laten we zeggen dat je het wel doet…

Wacht, waar zijn de foto’s? Is dat een logboeklezer? Gooi een 12-zijdige dobbelsteen, en als je een 8 gooit, kom je erachter dat die oogpictogrammen responsief zijn en, eenmaal aangeklikt, een miniatuur tonen. Sterker nog, als je op het oog in de kolomkop klikt, toont het alle miniaturen tegelijk. En verpest het de rijafstand, maar we gaan hier voor de chocolademedaille, dus dat is redelijk genoeg:

Ga zitten voor de rest, je bent er niet klaar voor:
- Het mappen-dingetje in de linkerkolom is eigenlijk een knop: als je erop klikt, verandert dat de volgorde waarin die mappen verschijnen.
- Het plaatsen-kader probeert de favorieten of bladwijzers van je bureaubladbeheerder na te bootsen, maar importeert ze niet.
- Het aanvinkvakje recursieve map is geen optie, het is een actie. Maar dan werkt het niet op wat je ook in de rechterkolom hebt geselecteerd, want dat zijn alleen foto’s. Wat het doet is de map nemen die in de linkerkolom is geselecteerd, en de lijst met foto’s vullen door recursief de geselecteerde map en zijn onderliggende mappen te doorzoeken.
- Het nieuwe foto’s selecteren is, wederom, geen optie maar een actie, oftewel iets wat de rest van de wereld in een knop stopt.
- Het veld datum van vandaag overschrijven is een omweg voor het feit dat de
EXIF-datum van de foto niet in mappatronen kan worden gebruikt, dus gebruiken we standaard de datum van vandaag. Behalve als dit veld is ingevuld. Maar het moet worden ingevuld met een datum-tijd volgens het ISO 8601-formaat. Wat ik hier niet deed, en het venster klaagt helemaal niet omdat validatie van formulierinvoer minder leuk is dan gebruikers bij de volgende stap laten ontdekken dat ze helemaal opnieuw moeten beginnen vanwege een verkeerd datum-tijdformaat. Jongens, dat is een hoop achtergrondkennis om verdorie een datum in te vullen, ik heb veel geluk dat ik dat allemaal heb geleerd door de broncode te lezen. - De optie oorspronkelijke bestandsnaam behouden is volledig overbodig ten opzichte van het gebruik van het naamgevingspatroon
$(FILE_NAME).$FILE_EXTENSION), - De naamgevingspatronen gebruiken variabelenmaskers
$()die tijdens runtime worden vervangen door de daadwerkelijke eigenschappen van het bestand, maar je moet ze kennen om ze te kunnen gebruiken. Alsof een gast genaamd Houz niet rond 2011 een bibliotheek heeft geschreven om automatisch aanvullen in tekstinvoer voor die variabelen te implementeren, die je gewoon in je code kunt aanroepen om het in 2 regels te laten werken (het wordt gebruikt in de exportmodule). - De naamgevingspatronen die daar te vinden zijn worden gedupliceerd in de voorkeuren-pop-up van Darktable omdat je ze mogelijk moet wijzigen wanneer je niets aan het importeren bent.
Dit is gemaakt van de grondstof van frustratie. Wat echt verbazingwekkend is, is hoeveel personen door de jaren heen aan deze functie hebben gewerkt om hier te komen. Sommigen zouden het collectieve intelligentie noemen, maar het heet eigenlijk ontwerp door commissie .
Een nieuwe aanpak, of het wegwerken van de slordigheid uit stap 0
Het importeren van afbeeldingen is echt stap 0 van het werken met welke beeldbewerkingsapplicatie dan ook. Het is onaanvaardbaar om gebruikers zo vroeg te verliezen, vooral omdat we later zoveel van hen verwachten, als het gaat om het begrijpen van licht en kleur. Maar ik zal betogen dat licht en kleur het dagelijkse brood zijn van elke grafisch kunstenaar, en het lijkt redelijk om van gebruikers van fotobewerking te verwachten dat ze op een gegeven moment de basis van hun vak beheersen.1 Anderzijds is het onaanvaardbaar om gebruikers te vragen hun masterdiploma in bestandskopiëren te halen.
Guillaume Stutin en ikzelf hebben daarom de importtool volledig herschreven, eerst de front-end en dan de back-end. Hier is het resultaat.

De optie om cameageheugenkaarten rechtstreeks vanuit GPhoto2 aan te koppelen is volledig verwijderd, aangezien besturingssystemen deze stap indien nodig rechtstreeks kunnen afhandelen. Er is slechts één toegangspunt om te importeren. Vervolgens krijg je het bestandskiezer-venster:

De bestandsverkenner is een native Gtk-bestandskiezerwidget, wat betekent dat de bladwijzers van het besturingssysteem (en zelfs hier de met Nextcloud gesynchroniseerde mappen) automatisch worden geïmporteerd vanuit de bureaubladomgeving. Het fotovoorbeeld is uitgebreid met EXIF-metadata om afbeeldingen beter te identificeren. Een opzoeking in de bibliotheekdatabase toont of de foto al dan niet al in Ansel of Darktable was geïmporteerd, en waar.2
Afbeeldingstypes (raw, niet-raw of alle) worden gefilterd met native Gtk-filters en de volledige lijst met te importeren bestanden wordt rechtstreeks in de GUI opgebouwd, zonder achteraf te twijfelen in de back-end. Wanneer mappen worden geselecteerd, wordt hun inhoud automatisch recursief doorzocht en wordt de eerste afbeelding van de collectie getoond. Het uiteindelijke aantal gedetecteerde afbeeldingen wordt onder de bestandskiezer weergegeven:

Vele sorteer- en weergaveopties worden native afgehandeld door de Gtk-bestandskiezer, waaronder zoeken (via Ctrl+F), zonder extra werk:

De optie voor bestandsafhandeling maakt het importeren met of zonder kopie mogelijk, het label legt het verschil in volle woorden uit:

De projectdatum wordt automatisch ingesteld op die van vandaag, geen overschrijving of iets wat zou suggereren dat er standaard iets ongeopenbaards gebeurt. Om de datum in te stellen wordt een kalenderwidget geboden die de datum automatisch in het juiste ISO-formaat opmaakt. Als de datum rechtstreeks in de tekstinvoer wordt getypt, wordt er een formaatvalidatie uitgevoerd en wordt er een foutmelding weergegeven:


Merk op dat de kalenderwidget alleen de datum (jaar, maand, dag) ondersteunt. Het instellen van de tijd (uur, minuut, seconde) moet handmatig in het tekstveld gebeuren. Enquêtes tonen dat dit zelden nodig is.
De naamgevingspatronen voor mappen en bestanden ondersteunen automatisch aanvullen van variabelen, wanneer $( wordt getypt. De nieuwe import-back-end ondersteunt het gebruik van EXIF-velden van afbeeldingen om mapnamen te definiëren, een mappatroon als $(JOBCODE)-$(EXIF.ISO) zou bijvoorbeeld foto’s opsplitsen in verschillende mappen die genoemd zijn naar hun ISO-metadata. Wanneer dit gebeurt, opent de lichttafel de laatst aangemaakte map wanneer het importvenster sluit:

Als laatste, maar zeker niet onbelangrijk, een door gebruikers gevraagde functie: het resultaat van de gedefinieerde patronen op de momenteel geselecteerde foto kunnen voorbeschouwen:

Het patroonresultaat volgt de geselecteerde bestanden en mappen, evenals elke wijziging in de hoofdmap en de patronen. Merk op dat de basismap (voor alle projecten) geen patronen meer accepteert, aangezien er geen reden is om overal patronen te plaatsen, wat het gebruik van een veilige en eenvoudige Gtk-mappenlijstwidget mogelijk maakt. Op deze manier wordt tenminste de bovenliggende Ansel-map op een robuuste en gebruiksvriendelijke manier ingesteld, en als er schade ontstaat door naamgevingspatronen, blijft die ingesloten binnen iets voorspelbaars.
Conclusie
Het moet worden opgemerkt dat dit eenvoudigere grafische ontwerp ook gepaard gaat met een veel eenvoudigere codestructuur, minder regels en een lineairdere logica. De front-end heeft 1200 regels nodig, en de back-end ongeveer 400 regels (inclusief commentaar, de nieuwe back-end heeft bijna overal Doxygen-docstrings). Een groot deel van het codevolume van de front-end komt van de recursieve mapdoorzoeker, die in een aparte thread draait om de GUI-thread niet te blokkeren, maar toch periodiek de bestandstellingen bijwerkt voor feedback. Dit is getest met mappen van meer dan 60.000 afbeeldingen.
Darktable heeft meer dan 2700 regels front-end en meer dan 800 regels back-end (geen docstrings). Bovendien verwacht de Darktable-architectuur één doelmap per importsessie, wat het gebruik van per-foto-EXIF in de naamgevingspatronen van mappen verbiedt, en heeft het volledig verschillende codepaden om de verschillen tussen met kopie/zonder kopie af te handelen. Dit maakt het moeilijk om beide paden synchroon te houden omdat ze nog steeds enkele stukjes delen (toevoegen aan de database en het initialiseren van metadata). In Ansel hebben we beide paden samengevoegd met slechts een optionele initiële I/O om de bestanden indien nodig te kopiëren.
De front-end en back-end van Ansels import communiceren via een oerdomme lijst met bestandspaden, wat betekent dat de back-end niet achteraf gaat twijfelen aan welke gebruikersbeslissing er ook in de GUI is genomen. Ook is alle GUI-code uit de back-end verwijderd. Dit is een generiek en robuust ontwerp dat alternatieve manieren mogelijk maakt om een lijst met te importeren bestanden te produceren, bijvoorbeeld headless (vanuit een script). Voorheen gebeurden dingen als JPG-filtering of het herordenen van bestanden in de back-end.3
De belangrijkste aantrekkingskracht van het opgeschoonde ontwerp is dat alle info die nodig is om te begrijpen wat wat is, rechtstreeks in het venster toegankelijk is, zonder documentatie te hoeven openen. In geval van conflicten met bestemmingsbestandsnamen tijdens het importeren met kopie worden gebruikers gewaarschuwd met een pop-upvenster en worden de bestaande bestanden nooit overschreven. Om nog maar te zwijgen van het feit dat het geheel op een typische bestandsverkenner lijkt.
Sommige gebruikers hebben ook de wens geuit om de bewerkingsfuncties van de software te gebruiken zonder lastiggevallen te worden met de eigenaardigheid van het interne digitale-assetsbeheer (voornamelijk de lichttafel). Deze nieuwe importeur stelt hen in staat om enkele afbeeldingen rechtstreeks in de donkere kamer te openen door dubbel te klikken op een bestand of te klikken op een bestand + te klikken op de importeren-knop, waardoor de lichttafel volledig wordt omzeild.
De naamgevingspatronen zijn uiteraard verwijderd uit de voorkeuren-pop-up (die overigens te vinden is via het algemene menu, via Bewerken → Voorkeuren, zoals in elke normale software).
Veel dank aan Guillaume Stutin voor zijn nauwgezette werk aan dit onderwerp.
Note
De nieuwe importeur is beschikbaar voor Ansel-buildversies > 0.0.0+780.Translated from English by : Claude. In case of conflict, inconsistency or error, the English version shall prevail.
Yes, I know it’s already too much to ask in most cases. ↩︎
This reuses the Darktable code but with a clearer display. ↩︎
The whole notion of back-end vs. front-end is new to the Darktable ecosystem, as you will find GUI (Gtk) functions pretty much everywhere, protected by a recurring
if(darktable.gui)to prevent segmentation faults when the software runs from CLI. ↩︎