O Ansel herda do Darktable sua espinha dorsal de banco de dados: os históricos de edição não destrutiva são salvos por imagem em um banco de dados SQLite, junto com metadados e outros dados definidos pelo usuário. Fazer com que o banco de dados reconheça novas imagens é feito através da “importação” de imagens de um disco ou de um cartão de memória. É aí que entra a ferramenta de importação.
Infelizmente, o importador do Darktable é outra coisa que foi massacrada por volta de 2020 e transformada em algo profundamente desconcertante, pois é um navegador de arquivos que não se parece com nenhum navegador de arquivos conhecido anteriormente, e consegue carecer de recursos básicos (como Ctrl+F ou pré-visualização de EXIF) enquanto ainda está inchado de recursos inúteis (veja abaixo). É aqui que perdemos muitos futuros usuários, e este é apenas o passo 0 do fluxo de trabalho. Que ótima demonstração do que um “aplicativo de fluxo de trabalho” é capaz de fazer!
Uma revisão de design do que o design por comitê vai lhe render
Então o Darktable tem os botãoes de importação em um widget da barra lateral. São 3 deles se você conectou uma câmera via USB, 2 caso contrário:

Muitas postagens de fórum foram desperdiçadas explicando repetidas vezes qual era a diferença entre adicionar à biblioteca e importar e copiar (importar na verdade significa adicionar à biblioteca). Também vale mencionar que o botão montar câmera não faz nada além do que qualquer driver PTP ou MTP de todo o sistema faz por você: montar o cartão SD interno como um armazenamento USB externo, através da porta USB da câmera. No Windows isso requer instalar um driver USB personalizado que impedirá sua câmera de funcionar com o resto do sistema operacional. No Linux, dependendo de o seu sistema operacional ter a “montagem automática” ativada, você pode ter que desmontar a câmera do navegador de arquivos do seu desktop primeiro, caso contrário ela bloqueará a conexão. Em todos os sistemas operacionais, isso requer ficar escutando novos dispositivos em segundo plano o tempo todo para que o aplicativo possa reagir à conexão a quente, quer você vá usar o recurso ou não.
E então, há os parâmetros. Desde 2022, a equipe do Darktable se apaixonou perdidamente por aquelas bandejas retráteis que escondem o inchaço debaixo de mais inchaço. E o inchaço que você encontra ali não faz nada além de apertar Ctrl+A (selecionar todas as imagens), e então 0 ou 1 (para atribuir uma classificação inicial de 0 ou 1 estrela) ou preencher a informação de metadados (em lote) no módulo homônimo, que fica na interface da mesa de luz quer você goste ou não, e suporta predefinições caso você sempre reutilize os mesmos metadados. A razão pela qual adicionar esses parâmetros ali chegou a ser um requisito em primeiro lugar está além da minha compreensão. Alguém, em algum lugar, está provavelmente economizando 0,5 s por sessão de importação, tempo que o resto do mundo está perdendo ao rolar mais altura.
Então, supondo que você entendeu as diferenças entre todas essas opções, agora você clica em importar e copiar, que é provavelmente a mais usada, já que qualquer fotógrafo precisa esvaziar os cartões SD para um armazenamento mais permanente. E então…

Isso é basicamente admitir que o design é tão terrível que está à beira de ser inutilizável sem ler a documentação. Mas espere, o que estamos fazendo mesmo? Estamos copiando imagens. Estamos copiando imagens? Então você passou no seu exame de cópia de imagens e obteve seu diploma de cópia de imagens? Se você não obteve, deveria. Cuidado, eles podem transformar isso em um teste em uma versão futura e desativar o recurso se você for reprovado.
Então você clica naquele botão ameaçador dizendo que você assume total responsabilidade por qualquer dano que possa acontecer ao copiar imagens. Ou você não clica, considerando que ele parece meio assustador. Mas vamos supor que você clique…

Espere, cadê as imagens? Isso é um leitor de log? Jogue um dado de 12 faces, e se tirar 8, você vai descobrir que aqueles ícones de olho são responsivos e, uma vez clicados, exibem uma miniatura. Diabos, se você clicar no olho no cabeçalho da coluna, ele mostrará todas as miniaturas de uma vez. E bagunçará o espaçamento das linhas, mas aqui estamos disputando a medalha de chocolate, então tá de bom tamanho:

Sente-se para o resto, você não está preparado:
- A coisinha de pastas na coluna da esquerda é na verdade um botão: quando você clica nele, isso muda a ordem de aparição daquelas pastas.
- O quadro lugares tenta emular os favoritos ou marcadores do gerenciador de desktop do seu sistema operacional, mas não os importa.
- A caixa de seleção diretório recursivo não é uma opção, é uma ação. Mas então ela não age sobre o que quer que você tenha selecionado na coluna da direita, porque aquilo são apenas imagens. O que ela faz é pegar a pasta selecionada na coluna da esquerda, e povoar a lista de imagens percorrendo recursivamente a pasta selecionada e suas filhas.
- O selecionar novas imagens é, mais uma vez, não uma opção, mas uma ação, ou seja, algo que o resto do mundo coloca em um botão.
- O campo sobrepor a data de hoje é uma solução alternativa para o fato de que a data
EXIFda imagem não pode ser usada em padrões de pastas, então por padrão usamos a data de hoje. Exceto se este campo estiver preenchido. Mas ele precisa ser preenchido com uma data e hora seguindo o formato ISO 8601. Coisa que eu não fiz aqui, e a janela não está reclamando nem um pouco, porque validar as entradas do formulário é menos divertido do que deixar os usuários descobrirem no próximo passo que eles têm que começar tudo de novo do zero por causa de um formato de data e hora inválido. Rapaz, é muito conhecimento de fundo para ter que preencher uma maldita data, tenho muita sorte de ter aprendido tudo isso lendo o código-fonte. - A opção manter o nome de arquivo original é totalmente redundante com o uso do padrão de nomenclatura
$(FILE_NAME).$FILE_EXTENSION), - Os padrões de nomenclatura usam máscaras de variáveis
$()que são substituídas em tempo de execução pelas propriedades reais do arquivo, mas você precisa conhecê-las para poder usá-las. Como se um sujeito chamado Houz não tivesse escrito uma biblioteca por volta de 2011 para implementar o preenchimento automático em entradas de texto para essas variáveis, que você pode simplesmente chamar no seu código para fazê-la funcionar em 2 linhas (ela é usada no módulo de exportação). - Os padrões de nomenclatura encontrados ali estão duplicados no pop-up de preferências do Darktable porque você pode precisar mudá-los quando não está importando nada.
Isso é feito do material da frustração. O que é verdadeiramente incrível é quantas pessoas trabalharam neste recurso ao longo dos anos para chegar a isso. Alguns chamariam de inteligência coletiva , mas na verdade se chama design por comitê .
Uma nova abordagem, ou apagando o desleixo do passo 0
Importar imagens é verdadeiramente o passo 0 de trabalhar com qualquer aplicativo de edição de imagens. É inaceitável perder usuários tão cedo, especialmente porque esperamos tanto deles mais tarde, quando se trata de entender luz e cor. Mas eu argumentarei que luz e cor são o feijão com arroz de qualquer artista gráfico, e parece justo esperar que os usuários de edição de fotos dominem o básico do seu ofício em algum momento.1 Por outro lado, pedir aos usuários que obtenham seu mestrado em cópia de arquivos é inaceitável.
Guillaume Stutin e eu, portanto, reescrevemos a ferramenta de importação inteiramente, primeiro o front-end e depois o back-end. Aqui está o resultado.

A opção de montar diretamente o cartão de memória das câmeras a partir do GPhoto2 foi removida inteiramente, já que os sistemas operacionais podem lidar com esse passo diretamente, se necessário. Há apenas um ponto de entrada para importar. Então você obtém a janela do seletor de arquivos:

O navegador de arquivos é um widget seletor de arquivos nativo do Gtk, o que significa que os marcadores do sistema operacional (e mesmo aqui as pastas sincronizadas do Nextcloud) são automaticamente importados do ambiente de desktop. A pré-visualização da imagem foi ampliada com metadados EXIF para melhor identificar as imagens. Uma consulta ao banco de dados da biblioteca mostra se a imagem já foi ou não importada para o Ansel ou o Darktable, e onde.2
Os tipos de imagem (raw, não-raw ou todos) são filtrados usando filtros nativos do Gtk e a lista completa de arquivos a importar é construída diretamente na interface gráfica, sem conjecturas no back-end. Quando pastas são selecionadas, seu conteúdo é percorrido automaticamente de forma recursiva e a primeira imagem da coleção é mostrada. O número final de imagens detectadas é exibido abaixo do seletor de arquivos:

Muitas opções de ordenação e exibição são tratadas nativamente pelo seletor de arquivos do Gtk, incluindo a busca (através de Ctrl+F), sem trabalho adicional:

A opção de manuseio de arquivos habilita a importação com ou sem cópia, e o rótulo explica a diferença por extenso:

A data do projeto é automaticamente definida como a de hoje, sem sobreposição ou qualquer coisa que sugira que algo não revelado esteja acontecendo por padrão. Para definir a data, um widget de calendário é fornecido, o qual formata automaticamente a data no formato ISO correto. Se a data for digitada diretamente na entrada de texto, uma validação de formato é realizada e um feedback de erro é exibido:


Note que apenas a data (ano, mês, dia) é suportada pelo widget de calendário. Definir a hora (hora, minuto, segundo) precisa ser feito manualmente no campo de texto. Pesquisas mostram que isso raramente é necessário.
Os padrões de nomenclatura de pastas e arquivos suportam o preenchimento automático de variáveis automaticamente, quando $( é digitado. O novo back-end de importação suporta o uso de campos EXIF das imagens para definir nomes de pastas; por exemplo, um padrão de pasta como $(JOBCODE)-$(EXIF.ISO) dividiria as imagens em várias pastas nomeadas de acordo com seus metadados de ISO. Quando isso acontece, a mesa de luz abre a última pasta criada quando a janela de importação é fechada:

Por último, mas não menos importante, um recurso solicitado pelos usuários: poder pré-visualizar o resultado dos padrões definidos na imagem atualmente selecionada:

O resultado do padrão acompanha os arquivos e pastas selecionados, bem como qualquer mudança na pasta principal e nos padrões. Note que o diretório base (para todos os projetos) não aceita mais padrões, já que não há razão para colocar padrões em todo lugar, o que permite usar um widget de lista de pastas do Gtk seguro e simples. Dessa forma, ao menos a pasta Ansel de nível superior é definida de uma maneira robusta e amigável, e se danos acontecerem por causa dos padrões de nomenclatura, ficarão contidos dentro de algo previsível.
Conclusão
Deve-se notar que este design gráfico mais simples vem também com uma estrutura de código muito mais simples, menos linhas e uma lógica mais linear. O front-end precisa de 1200 linhas, e o back-end de cerca de 400 linhas (comentários incluídos, o novo back-end tem docstrings Doxygen em quase todo lugar). Uma grande parte do volume de código do front-end vem do rastreador recursivo de pastas, que roda em uma thread separada para não bloquear a thread da interface gráfica, mas ainda assim atualiza as contagens de arquivos periodicamente para fornecer feedback. Isso foi testado com pastas de mais de 60.000 imagens.
O Darktable tem mais de 2700 linhas de front-end e mais de 800 linhas de back-end (sem docstrings). Além disso, a arquitetura do Darktable espera uma pasta de destino por sessão de importação, o que proíbe o uso de EXIF por imagem nos padrões de nomenclatura de pastas, e tem caminhos de código completamente diferentes para lidar com as discrepâncias entre com cópia/sem cópia. Isso torna difícil manter ambos os caminhos sincronizados porque eles ainda compartilham algumas partes (adicionar ao banco de dados e inicializar metadados). No Ansel, mesclamos ambos os caminhos com apenas uma E/S inicial opcional para copiar os arquivos, se necessário.
A importação do front-end e do back-end do Ansel se comunicam através de uma lista extremamente simples de caminhos de arquivos, o que significa que o back-end não fica conjecturando qualquer decisão de usuário que tenha sido tomada na interface gráfica. Além disso, todo o código de interface gráfica foi removido do back-end. Este é um design genérico e robusto que permitirá maneiras alternativas de produzir uma lista de arquivos a importar, por exemplo sem interface (a partir de um script). Anteriormente, coisas como a filtragem de JPG ou a reordenação de arquivos aconteciam no back-end.3
O principal apelo do design enxuto é que toda a informação necessária para entender o que é o quê está acessível diretamente na janela, sem ter que abrir uma documentação. Em caso de conflitos de nome de arquivo de destino durante a importação com cópia, os usuários são avisados com uma janela pop-up e os arquivos existentes nunca são sobrescritos. Sem falar que a coisa toda se parece com um típico navegador de arquivos.
Alguns usuários também expressaram o desejo de usar os recursos de edição do software sem serem incomodados com a estranheza do gerenciamento interno de ativos digitais (a mesa de luz, principalmente). Este novo importador permite que eles abram imagens individuais diretamente na sala escura através de um clique duplo no arquivo ou clique no arquivo + clique no botão importar, contornando efetivamente a mesa de luz por completo.
Os padrões de nomenclatura foram, é claro, removidos do pop-up de preferências (que, aliás, pode ser encontrado no menu global, através de Editar → Preferências, como em qualquer software sensato).
Muito obrigado a Guillaume Stutin pelo seu trabalho árduo neste tópico.
Note
O novo importador está disponível para as versões de compilação do Ansel > 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. ↩︎