Posso usar o terminal para mover imagens para dirs específicas usando a tag de imagens?

1

Eu tenho uma enorme pasta de imagens que colecionei ao longo dos anos que meus alunos usam para cursos. Começou com cerca de vinte imagens, então eu realmente não me incomodei com nomes de arquivos ou qualquer tipo de estrutura, apenas os etiquetei e os joguei. Essa mesma pasta agora tem cerca de 5000 imagens e está chegando ao ponto em que é difícil trabalhar com.

Idealmente, gostaria de poder executar um comando (agora e no futuro, à medida que mais sejam enviados), que examinaria a (s) tag (s) de imagens e criaria um diretório com o nome da tag e moveria essa imagem. ou se uma imagem anterior já tiver criado esse diretório, simplesmente mova a imagem para esse diretório.

Não sei se estou fazendo um ótimo trabalho explicando isso.

As primeiras 5 imagens, por exemplo, são carros - BMW, Honda, Ford, Alfa Romeo e outro BMW. Os nomes dos arquivos são todos únicos - todos eles estão na mesma pasta, lembre-se. Então, após a execução deste script mítico, eu teria 4 pastas com as duas imagens no BMW.

Tudo está marcado em Shotwell, é principalmente JPG com alguns PNG's usados apenas para complicar as coisas! Pode haver várias tags, mas 95% são apenas as únicas. Não tenho certeza de onde as tags estão armazenadas, mas estou assumindo em cada arquivo, já que as tags aparecem nos dois computadores, mas só foram marcadas na principal delas.

Outras investigações mostraram que as tags estão sendo armazenadas contra as "palavras-chave" da imagem individual, então talvez eu devesse estar perguntando como criar diretórios com base em suas palavras-chave?

Estou aprendendo muito enquanto vou aqui!

Se isso ajudar, esta é a saída do exiftool :

$ exiftool 010.jpg
ExifTool Version Number         : 10.10
File Name                       : 010.jpg
Directory                       : .
File Size                       : 274 kB
File Modification Date/Time     : 2016:04:23 21:03:59+01:00
File Access Date/Time           : 2016:04:23 21:03:59+01:00
File Inode Change Date/Time     : 2016:04:23 21:03:59+01:00
File Permissions                : rw-rw-r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : inches
X Resolution                    : 72
Y Resolution                    : 72
Exif Byte Order                 : Little-endian (Intel, II)
Software                        : Shotwell 0.22.0
XMP Toolkit                     : XMP Core 4.4.0-Exiv2
Subject                         : BMW, Bell_Photography
Current IPTC Digest             : 6249bf63f46e9abb15cfe27d71a87a72
Keywords                        : BMW, Bell_Photography
Originating Program             : Shotwell
Program Version                 : 0.22.0
Image Width                     : 936
Image Height                    : 1334
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:4:4 (1 1)
Image Size                      : 936x1334
Megapixels                      : 1.2

Assumindo que faz sentido para qualquer um além de mim, é possível?

    
por Dave 23.04.2016 / 20:17

2 respostas

3

Você pode usar exiftool para obter informações meta de jpg, png arquivos. Para instalar o exiftool , execute:

$ sudo apt-get install libimage-exiftool-perl

Uso: exiftool -s example.jpg

Parece que a informação mais completa é armazenada como TagsList . Ele ainda suporta tags hierárquicas salvas pelo Shotwell, por exemplo, nature/sky . As tags também podem ser encontradas nos campos Subject , Keywords , LastKeywordXMP . Subject , Keywords não preserva a hierarquia de tags - você pode usá-los se não quiser criar diretórios aninhados para tags aninhadas.

Este é o script python3 que move os arquivos de imagem especificados na linha de comando para os diretórios de tag correspondentes (criando hardlinks e removendo o nome do arquivo original), por exemplo, se example.jpg tiver a lista de tags: nature , nature/clouds , nature/mountain , nature/sky , a árvore do diretório de resultados se parece com:

.
└── nature
    ├── clouds
    │   └── example.jpg
    ├── example.jpg
    ├── mountain
    │   └── example.jpg
    └── sky
        └── example.jpg

Nota: sempre faça backup de seus dados antes de executar comandos potencialmente destrutivos (erros acontecem) :

#!/usr/bin/env python3
"""Move image files to their tag directories by creating hardlinks.

Usage: move-to-tag-dirs <image>...
"""
import json
import os
import sys
from subprocess import Popen, PIPE

TAGNAMES = ['TagsList', 'Keywords', 'Subject']
__version__ = '0.3.1'


def move_to_dirs(filename, dirs):
    """Move *filename* to *dirs* by creating hardlinks.

    Create destination directories if they don't exist.
    """
    for dirname in dirs:
        os.makedirs(dirname, exist_ok=True)
        dest_filename = os.path.join(dirname, os.path.basename(filename))
        os.link(filename, dest_filename)  # create hardlink
    if dirs:  # created at least one new link
        os.unlink(filename)  # remove old


if len(sys.argv) < 2:
    sys.exit(__doc__)  # print usage

command = ['exiftool', '-json'] + ['-' + t for t in TAGNAMES] + sys.argv[1:]
try:
    process = Popen(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
except OSError as e:
    sys.exit("error: can't start exiftool: " + str(e))
else:
    output, errors = process.communicate()
    if process.returncode != 0:
        sys.exit("error: can't read tags info: exiftool exit code: %d: %s" % (
            process.returncode, errors))

for metadata in json.loads(output):
    # get first available tags list
    dirs = next(filter(None, map(metadata.get, TAGNAMES)), [])
    if isinstance(dirs, str):  # single tag
        dirs = [dirs]
    try:
        move_to_dirs(metadata['SourceFile'], dirs)
    except OSError as e:
        print("warning: failed to move %s to %s: %s" % (
            metadata['SourceFile'], dirs, e), file=sys.stderr)

Salve-o em um arquivo chamado move-to-tag-dirs em algum lugar em $PATH . Certifique-se de que o arquivo tenha permissões executáveis:

$ chmod +x move-to-tag-dirs

Relacionados: Como executar um programa .py diretamente?

Em seguida, para mover todas as imagens para os diretórios de tags correspondentes, execute:

$ move-to-tag-dirs *.jpg *.png

Se você obtiver 'Argument list too long' de erro, execute:

$ find . -maxdepth 1 -name \*.jpg -o -name \*.png -exec move-to-tag-dirs {} +

Veja Resolvendo “mv: lista de argumentos muito longa”?

Se você ignorar tratamento de erros, suporte a tags hierárquicas, suporte a caracteres incomuns em nomes de arquivos, tags, etc., o script poderia ser simplificado significativamente (talvez um shell script simples fosse suficiente nesse caso).

    
por jfs 24.04.2016 / 11:14
3

Embora a resposta de JF Sebastian seja provavelmente o que você está procurando, existe também um sistema de arquivos baseado em tags denominado tagsistant que pode valer a pena investigar. Você pode tratar suas tags como diretórios em sistemas de arquivos convencionais e navegar em seus arquivos por navegação. Isso torna mais fácil se você tiver várias tags em um arquivo e quiser pesquisar e classificar por elas.

    
por emk2203 24.04.2016 / 16:29