Ansel hérite de Darktable son infrastructure de base de données : les historiques de modifications non destructifs sont sauvegardés image par image dans une base de données SQLite, avec les métadonnées et autres données définies par l’utilisateur. Pour intégrer de nouvelles images à la base de données, il faut « importer » ces images depuis un disque ou une carte mémoire. C’est à cela que sert l’outil d’importation.
Malheureusement, l’importateur de Darktable est une autre fonctionnalité qui a été massacrée autour de 2020 pour devenir quelque chose de profondément déroutant : un navigateur de fichiers ne ressemblant à aucun navigateur connu jusqu’alors, qui parvient à manquer de fonctions de base (comme Ctrl+F ou un aperçu EXIF) tout en étant encombré d’options inutiles (voir ci-dessous). C’est ainsi que nous perdons beaucoup d’utilisateurs potentiels dès l’étape zéro du flux de travail. Quel bel exemple de ce qu’une « application de workflow » peut faire !
Un examen critique de ce que produit une conception par comité
Donc, Darktable possède des boutons d’importation dans un widget situé sur une barre latérale. Il y en a 3 si vous avez connecté un appareil photo par USB, sinon il y en a 2 :
De nombreux messages sur les forums ont été perdus à expliquer encore et encore quelle était la différence entre ajouter à la bibliothèque et importer et copier (importer signifie en fait ajouter à la bibliothèque). Il convient également de mentionner que le bouton montage caméra ne fait rien de plus que ce que n’importe quel pilote PTP ou MTP à l’échelle du système fait pour vous : monter la carte SD interne comme un stockage USB externe, via le port USB de la caméra. Sous Windows, cela nécessite d’installer un pilote USB personnalisé qui empêchera votre caméra de fonctionner avec le reste du système d’exploitation. Sous Linux, en fonction de la configuration d’« auto-mount » de votre OS, vous devrez peut-être démonter la caméra depuis votre explorateur de fichiers de bureau d’abord, sinon elle verrouillera le lien. Sous tous les OS, cela nécessite d’écouter les nouveaux appareils en arrière-plan tout le temps pour que l’application puisse réagir au hot-plugging, que vous utilisiez ou non la fonctionnalité.
Et puis, il y a les paramètres. Depuis 2022, l’équipe Darktable est tombée folle amoureuse de ces plateaux rétractables qui cachent le superflu sous plus de superflu. Et le superflu que vous pouvez y trouver ne fait rien de plus que d’appuyer sur Ctrl+A (sélectionner toutes les photos), puis sur 0 ou 1 (pour attribuer une note initiale de 0 ou 1 étoile) ou de remplir les infos des métadonnées (en lot) dans le module éponyme, qui se trouve dans l’interface de la table lumineuse que vous le vouliez ou non, et prend en charge les presets au cas où vous réutiliseriez toujours les mêmes métadonnées. La raison pour laquelle l’ajout de ces paramètres était même initialement requis m’échappe. Quelqu’un, quelque part, épargne probablement 0,5 s par session d’importation, que le reste du monde perd en défilant plus de hauteur.
Donc, à condition de comprendre les différences entre toutes ces options, maintenant vous cliquez sur importer et copier, qui est probablement le plus utilisé car tout photographe a besoin de vider les cartes SD sur un stockage plus permanent. Et puis…
C’est essentiellement admettre que la conception est si terrible que c’est à la limite de l’inutilisable sans lire la documentation. Mais attendez, que faisons-nous encore ? Nous copions des images. Nous copions des images ? Alors avez-vous passé votre examen de copie d’images et obtenu votre diplôme de copie d’images ? Si ce n’est pas le cas, vous devriez le faire. Attention, ils pourraient en faire un quiz dans une future version et désactiver la fonctionnalité si vous échouez.
Donc vous cliquez sur ce bouton ominieux disant que vous assumez l’entière responsabilité de tout dommage pouvant résulter de la copie des images. Ou pas, étant donné que cela semble un peu effrayant. Mais disons que vous le faites…
Attendez, où sont les images ? Est-ce un lecteur de journal ? Lancez un dé à 12 faces, et si vous faites un 8, vous découvrirez que ces icônes d’yeux sont réactives et, une fois cliquées, affichent une vignette. Bon sang, si vous cliquez sur l’œil dans l’en-tête de colonne, cela affichera toutes les vignettes d’un coup. Et perturbera l’espacement des lignes, mais nous courons pour la médaille en chocolat ici, donc c’est assez juste :
Restez assis pour la suite, vous n’êtes pas prêt :
- Le machin dossiers sur la colonne de gauche est en fait un bouton : lorsque vous cliquez dessus, cela change l’ordre d’apparition de ces dossiers.
- Le cadre lieux essaie d’émuler les favoris ou les signets de votre gestionnaire de bureau OS, mais ne les importe pas.
- La case à cocher répertoire récursif n’est pas une option, c’est une action. Mais elle n’agit pas sur ce que vous avez sélectionné dans la colonne de droite, car ce ne sont que des images. Ce qu’elle fait, c’est prendre le dossier sélectionné dans la colonne de gauche, et remplir la liste des images en parcourant de manière récursive le dossier sélectionné et ses enfants.
- La sélection de nouvelles images n’est, encore une fois, pas une option mais une action, c’est-à-dire quelque chose que le reste du monde met dans un bouton.
- Le champ remplacer la date d’aujourd’hui est un contournement du fait que la date EXIF de l’image ne peut pas être utilisée dans les modèles de dossiers, donc par défaut nous utilisons la date d’aujourd’hui. Sauf si ce champ est rempli. Mais il doit être rempli avec une date et une heure suivant le format ISO 8601. Ce que je n’ai pas fait ici, et la fenêtre ne se plaint pas du tout parce que valider les entrées de formulaire est moins amusant que de laisser les utilisateurs découvrir à l’étape suivante qu’ils doivent recommencer à zéro à cause d’un mauvais format de date-heure. Garçon, c’est beaucoup de connaissances préalables à avoir pour remplir une fichue date, j’ai beaucoup de chance d’avoir appris tout ça en lisant le code source.
- L’option conserver le nom de fichier d’origine est totalement redondante avec l’utilisation du schéma de dénomination
$(FILE_NAME).$FILE_EXTENSION)
. - Les schémas de dénomination utilisent des masques de variables
$()
qui sont remplacés à l’exécution par les propriétés réelles du fichier, mais vous devez les connaître pour pouvoir les utiliser. Comme si un type nommé Houz n’avait pas écrit une bibliothèque vers 2011 pour implémenter l’auto-complétion dans les entrées de texte pour ces variables, que vous pouvez simplement appeler dans votre code pour le faire fonctionner en 2 lignes (elle est utilisée dans le module export). - Les schémas de dénomination trouvés là sont dupliqués dans la fenêtre des préférences de Darktable car vous pourriez avoir besoin de les changer quand vous n’importez rien.
C’est fait de la matière de la frustration. Ce qui est vraiment incroyable, c’est combien de personnes ont travaillé sur cette fonctionnalité au fil des années pour en arriver là. Certains l’appelleraient intelligence collective, mais en réalité c’est ce qu’on appelle conception par comité.
Une nouvelle approche, ou effacer les doutes dès l’étape 0
L’importation d’images est vraiment l’étape 0 du travail avec n’importe quelle application d’édition d’images. Il est inacceptable de perdre des utilisateurs si tôt, surtout depuis que nous attendons beaucoup d’eux plus tard, lorsqu’il s’agit de comprendre la lumière et la couleur. Mais je dirais que la lumière et la couleur sont le pain et le beurre de tout artiste graphique, et il semble juste de s’attendre à ce que les utilisateurs de logiciels de retouche photo maîtrisent les bases de leur métier à un moment donné.1 D’un autre côté, demander aux utilisateurs d’obtenir leur diplôme en copie de fichiers est inacceptable.
Guillaume Stutin et moi avons donc complètement réécrit l’outil d’importation, d’abord le front-end et ensuite le back-end. Voici le résultat.
L’option de monter directement les cartes mémoire des appareils photo depuis GPhoto2 a été entièrement supprimée, puisque les OS peuvent gérer cette étape directement si nécessaire. Il n’y a qu’un seul point d’entrée pour importer. Puis, vous obtenez la fenêtre de sélection de fichiers :
Le navigateur de fichiers est un widget sélecteur de fichiers Gtk natif, ce qui signifie que les signets du système d’exploitation (et même ici les dossiers synchronisés Nextcloud) sont automatiquement importés depuis l’environnement de bureau. L’aperçu de l’image a été étendu avec les métadonnées EXIF pour mieux identifier les images. Une recherche dans la base de données de la bibliothèque montre si l’image a déjà été importée dans Ansel ou Darktable, et où.2
Les types d’images (raw, non-raw ou tous) sont filtrés à l’aide de filtres Gtk natifs et la liste complète des fichiers à importer est construite directement dans l’interface graphique, sans seconde conjecture en backend. Lorsqu’un dossier est sélectionné, son contenu est automatiquement exploré de manière récursive et la première image de la collection est affichée. Le nombre final d’images détectées est affiché sous le sélecteur de fichiers :
De nombreuses options de tri et d’affichage sont gérées nativement par le sélecteur de fichiers Gtk, y compris la recherche (via Ctrl+F), sans travail supplémentaire :
L’option de gestion des fichiers permet l’importation avec ou sans copie, le libellé explique clairement la différence :
La date du projet est automatiquement fixée à la date du jour, sans modification cachée ni comportement inattendu par défaut. Pour régler la date, un widget calendrier est fourni, qui formate automatiquement la date au bon format ISO. Si la date est saisie directement dans le champ texte, une validation du format est effectuée et un message d’erreur s’affiche si nécessaire :


Notez que seul le choix de la date (année, mois, jour) est pris en charge par le widget calendrier. La saisie de l’heure (heures, minutes, secondes) doit être effectuée manuellement dans le champ texte. Les enquêtes indiquent que cela est rarement nécessaire.
Les modèles de nommage des dossiers et fichiers prennent en charge l’autocomplétion automatique des variables dès que $(
est saisi. Le nouveau système d’importation permet d’utiliser les champs EXIF des images pour définir le nom des dossiers. Par exemple, un modèle de dossier tel que $(JOBCODE)-$(EXIF.ISO)
répartirait les images dans différents dossiers selon leurs métadonnées ISO. Dans ce cas, la table lumineuse ouvre automatiquement le dernier dossier créé à la fermeture de la fenêtre d’importation :
Enfin, une fonctionnalité demandée par les utilisateurs : la possibilité de prévisualiser le résultat des modèles définis sur l’image actuellement sélectionnée :
Le résultat du modèle suit les fichiers et dossiers sélectionnés ainsi que toute modification du dossier principal et des modèles. Notez que le répertoire principal (pour tous les projets) n’accepte plus les modèles, car il n’y a pas de raison d’en placer partout, ce qui permet d’utiliser un widget Gtk de liste de dossiers simple et sécurisé. Ainsi, au moins le dossier principal d’Ansel est défini de manière robuste et conviviale, et tout problème résultant des modèles de nommage restera contenu dans une structure prévisible.
Conclusion
Il convient de noter que cette conception graphique simplifiée s’accompagne également d’une structure de code beaucoup plus simple, avec moins de lignes et une logique plus linéaire. L’interface utilise environ 1200 lignes de code et l’arrière-plan environ 400 lignes (commentaires compris, le nouveau back-end est documenté avec Doxygen presque partout). Une grande partie du code côté interface concerne l’exploration récursive des dossiers, exécutée dans un thread séparé pour ne pas bloquer le thread principal, tout en mettant périodiquement à jour les compteurs de fichiers pour retour visuel. Cela a été testé sur des dossiers contenant plus de 60 000 images.
Darktable possède plus de 2700 lignes d’interface graphique et plus de 800 lignes de back-end (sans documentation). De plus, son architecture suppose un dossier cible unique par session d’importation, ce qui interdit l’utilisation des champs EXIF par image dans les modèles de nommage des dossiers, et impose des chemins de code distincts pour les importations avec ou sans copie. Cela rend difficile leur synchronisation car certains éléments sont partagés (ajout à la base de données, initialisation des métadonnées). Dans Ansel, nous avons fusionné les deux chemins avec simplement une opération d’entrée/sortie optionnelle pour copier les fichiers si nécessaire.
Dans Ansel, l’interface graphique et le back-end communiquent via une simple liste de chemins de fichiers, ce qui signifie que le back-end ne remet pas en question les décisions prises par l’utilisateur dans l’interface. De plus, tout le code lié à l’interface graphique a été retiré du back-end. Ce design générique et robuste permettra d’autres moyens de produire des listes de fichiers à importer, par exemple en mode sans interface graphique (script en ligne de commande). Auparavant, dans Darktable, le filtrage des JPG et le tri étaient gérés par le back-end.3
Le principal avantage de cette conception simplifiée est que toutes les informations nécessaires à la compréhension sont directement accessibles dans la fenêtre, sans avoir besoin d’ouvrir une documentation. En cas de conflit de nom lors de l’importation avec copie, l’utilisateur est averti par une fenêtre contextuelle et aucun fichier existant n’est écrasé. De plus, l’ensemble ressemble enfin à un navigateur de fichiers classique.
Certains utilisateurs ont exprimé le souhait de pouvoir utiliser les fonctionnalités d’édition du logiciel sans être gênés par la gestion interne des ressources numériques (principalement la table lumineuse). Ce nouvel importateur leur permet d’ouvrir directement une image dans la chambre noire en double-cliquant sur un fichier ou en cliquant sur un fichier puis sur le bouton importer, contournant ainsi totalement la table lumineuse.
Les modèles de nommage ont bien sûr été supprimés de la fenêtre des préférences (que l’on trouve désormais via le menu global : Édition → Préférences, comme dans tout logiciel sensé).
Un grand merci à Guillaume Stutin pour son travail méticuleux sur ce sujet.
Note
Le nouvel importateur est disponible pour les versions d’Ansel > 0.0.0+780.Translated from English by : Aurélien Pierre, ChatGPT. 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. ↩︎