Problemas de corrupção se eu parar de converter imagemagick

2

Eu quero redimensionar um monte de imagens (cerca de 1 milhão) usando a função de conversão imageMagick. Estou usando o Ubuntu 16.04

Isso está demorando mais do que eu pensava (estava correndo cerca de 5 horas - posso dar mais 5, mas depois quero pará-lo)

Minha pergunta é: se eu parar o programa, terei que me preocupar com imagens corrompidas? Ou o programa será interrompido de forma segura?

Este é o meu script:

find . -name "*.JPEG" | xargs -I {} convert {} -resize "256^>" {}

(Basicamente estou redimensionando o conjunto de dados imagenet)

Pressionar Ctrl-C pode corromper algumas imagens?

    
por Ant 10.12.2017 / 15:40

3 respostas

4

Em teoria, não, isso não deve resultar em imagens corrompidas. Na memória, acho que imagemagick trabalha com arquivos temporários, que são renomeados para o arquivo de destino escolhido depois que o processamento é feito.

BTW converter imagens do jeito que você fez é uma operação unidirecional, eu acho que você notou isso, daí a sua pergunta, eu acho.

Para descobrir qual imagem foi convertida por último, liste os arquivos em ordem cronológica, primeiro os arquivos mais recentes. Se houver uma diferença notável no tamanho do arquivo, você saberá com facilidade por onde começar da próxima vez. Caso contrário, você terá que recuperar as dimensões da imagem usando a identificação do imagemagick .

Observe também que, para um milhão de imagens, se cada imagem for processada em um segundo, isso ainda exigirá que cerca de 280 horas sejam concluídas. Espero que você tenha uma máquina rápida e poderosa ...

EDIT: Se você quiser mostrar algum progresso , aqui está o que posso pensar, com base em Resposta de Martin :

mkdir -p thumbs; \
COUNT=$(find -name "*.JPEG" | wc -l); \
find -name "*.JPEG" | while read IMG; do \
    printf "\n$(( ++i )) / $COUNT\n" && \
    [ -s "thumbs/${IMG%.JPEG}-small.jpg" ] || \
    convert "$IMG" -resize "256^>" "thumbs/${IMG%.JPEG}-small.jpg"; \
done

O que isso faz:

  1. crie o diretório de miniaturas ...
  2. conte o número total de .JPEG images ...
  3. para cada imagem ...
  4. imprime o índice do arquivo de imagem atual em relação ao total ...
  5. se a imagem ainda não foi convertida ...
  6. crie uma miniatura dela.

Supondo que todas as imagens para redimensionar estão no mesmo diretório, usei um subdiretório para salvar as imagens em miniatura para evitar bagunçar o diretório principal com as miniaturas correspondentes. Caso contrário, você poderá remover a primeira linha e o subdiretório thumbs/ da quinta e sexta linha.

Se as imagens estiverem espalhadas em subdiretórios:

COUNT=$(find -name "*.JPEG" | wc -l); \
find -name "*.JPEG" | while read IMG; do \
    printf "\n$(( ++i )) / $COUNT\n" && \
    [ -s "${IMG%.JPEG}-small.jpg" ] || \
    convert "$IMG" -resize "256^>" "${IMG%.JPEG}-small.jpg"; \
done

Observe que esse script considera espaços em nomes de arquivos, pois a leitura é interrompida em um novo caractere de linha.

    
por 10.12.2017 / 16:22
3

Não é uma boa ideia combinar find e xargs desta forma. Nomes de arquivos com espaços e outros caracteres que possuem um significado especial na linha de comando podem atrapalhar as coisas. É melhor usar

find . -name '.JPEG' -print -exec convert '{}' -resize "256^>" '{}-small.jpg' \;

Em seu comando, parece que você sobrescreve as imagens, está correto? O problema é que convert não é necessariamente uma operação atômica . Seria muito melhor se você tivesse feito isso:

shopt -s extglob
for i in **/*.jpg; do
  convert "$i" -resize "256^>" tmp.jpg
  mv tmp.jpg "$i"
done

O comando mv provavelmente é atômico. Se você interromper isso em qualquer lugar, o único dano poderia ser um tmp.jpg em algum lugar.

Se você pressionar Ctrl C agora, você irá cancelar o comando convert . Se isso capturar o sinal de interrupção, ele pode terminar de gravar a imagem, mas também pode parar de escrever.

Você pode mover toda a estrutura de diretórios para outro lugar, se tiver sorte, a gravação será concluída, mas todas as novas chamadas convert falharão.

Por que você não tenta verificar até onde foi o processo? find não fornece saída ordenada, então você teria que escanear os tamanhos das imagens em seus diretórios e verificar quantos já são redimensionados.

    
por 10.12.2017 / 16:23
3

Pelo que entendi (e eu tenho certeza que as pessoas vão usar o chip para corrigir se houver algum erro) Ctrl + C envia SIGINT para bash e para quaisquer scripts e processos-filhos / threads em execução.

Bash quebra o script no próximo ponto em que recupera qualquer controle (como a próxima iteração de um loop, ou quando uma chamada é feita através de um pipe), outros processos são notificados do sinal e saem de acordo com o próprio estratégia, se eles tiverem um.

Se existe algum risco real de perda de dados depende de quão graciosamente convert captura e manipula o SIGINT . Um pedaço de código bem escrito (e convert já existe há algum tempo) lidaria com isso graciosamente e sairia sem danos.

ps -eT | grep -i convert

deve mostrar quantos encadeamentos estão sendo executados e quantas imagens estão em 'risco', embora considerando que o ciclo de gravação é consideravelmente menor que o tempo de processamento de cada imagem, você teria o azar de danificar mais de uma ou duas imagens mesmo se convert simplesmente largasse tudo quando o sinal pousasse.

    
por 10.12.2017 / 16:50