Como encontrar todas as imagens com um determinado tamanho de pixel usando a linha de comando?

16

Estou tentando encontrar todas as imagens JPG dentro de uma pasta com subpastas que tenham largura ou altura abaixo de 300px.

Dessa forma, desejo detectar miniaturas antigas e excluí-las.

Com certeza eu posso encontrar todas as imagens usando find:

find . -iname "*.jpg" -type f | ...

Mas o que se segue depois do cano? Qual pacote posso usar para detectar os atributos da imagem?

mcbetz
fonte

Respostas:

17

Você pode usar identifyfrom imagemagicke você pode usar o seguinte comando:

find . -iname "*.jpg" -type f -exec identify -format '%w %h %i' '{}' \; | awk '$1<300 || $2<300'

o uso de -exec <command> '{}' \;garante que seu nome de arquivo possa ter espaços, ou você pode usar

find . -iname "*.jpg" -type f | xargs -I{} identify -format '%w %h %i' {} | awk '$1<300 || $2<300'

onde o -I{}cuida da mesma coisa.

O que eu gosto identifyé que você pode especificar o formato de saída; neste caso, '%w %h %i'que fornece a largura, altura e nome do caminho completo da imagem. Em seguida, a awkexpressão mantém apenas as linhas para as quais a imagem é menor que o tamanho desejado.

Exemplo da saída:

64 64 ./thumbsup.jpg
100 150 ./photomin.jpg

Editar: se você deseja apenas os nomes dos arquivos (para canalizar, rmpor exemplo), basta alterar $linea awkinstrução para $3, então ela imprimirá apenas a terceira coluna.

Gerhard Burger
fonte
3
A parte awk pode ser reduzida: | awk '$1<300||$2<300'ou | awk '$1<300||$2<300{print $3}'(quando apenas a terceira coluna for necessária).
har-wradim
@ har-wradim Obrigado, boa sugestão!
Gerhard Burger
7
Eu tive que adicionar uma nova linha ( '%w %h %i\n') para fazê-la funcionar para mim.
QWR
Desculpe por escrever em uma pergunta de 6 anos, mas este é o único resultado que encontro no Google que parcialmente responde à minha pergunta. Basicamente, o que eu quero é encontrar imagens com ou dentro de dimensões específicas e copiá-las para outro diretório. Eu sei que o cp é usado para copiar, mas falho ao integrar esse comando ao cp.
GhostOrder
O @GhostOrder segue a sugestão do @ har-wradim para imprimir apenas a 3ª coluna e depois adiciona outro canal com algo parecido com isto| xargs -I {} mv {} /destination/directory/
Gerhard Burger
1

Acho que a resposta aceita é muito boa, mas queria acrescentar outra solução possível ...

Embora eu mesmo use as ImageMagickferramentas com mais frequência agora, netpbmsou um velho amigo para processar imagens. Você pode ver o tamanho de qualquer formato de imagem com o comando:

anytopnm file | pamfile

Isso irá gerar uma saída parecida com:

stdin:  PPM raw, 1650 by 1275  maxval 255

Para responder à pergunta "o que segue depois do tubo?", Uso com while readmais frequência do que uso, xargsporque é mais flexível. Minha netpbmresposta para a pergunta é assim:

find -iname \*.jpg | while read img; do \
  anytopnm "$img" | pamfile | \
    perl -ane 'exit 1 if $F[3]<300 || $F[5]<300' || rm -v "$img"; \
done
NateT
fonte
1

Isso funcionou para mim:

find . -iname "*.png" -type f -exec identify -format '%i %wx%h\n' '{}' \; | grep '75x75'

Esta é a amostra de saída:

./2520161636481000.png 75x75

./2620160819191100.png 75x75

./2420181545550700.png 75x75

osroflo
fonte
0

O identifycomando do imagemagickpacote faz o que você deseja:

$ identify abc.jpg
abc.jpg JPEG 1952x3264 1952x3264+0+0 8-bit DirectClass 1.111MB 0.000u 0:00.000

Novamente, você precisaria usar greppara classificar o tamanho da imagem.

No entanto, suspeito que, a menos que você tenha uma variedade muito grande de tamanhos de imagem, seria mais fácil usar apenas findpara remover arquivos JPEG abaixo de um determinado tamanho:

find -iname '*.jpg' -size -10k -delete

(Vale a pena correr sem -deleteprimeiro verificar se não encontra as coisas que você deseja manter - não será solicitado antes da exclusão).

cronite
fonte