fennecConvert: Um pequeno conversor de Imagens
23 May 2026 (updated: 23 May 2026 )
Eu havia mencionado numa notinha do madebyromeo, que o XnConvert não estava funcionando direito, mas eu tinha deixado pra lá, pois ele, malemá, estava funcionando. Mas ao migrar para o Void Linux decidi algo: Fazer o meu próprio Script de Conversão de Imagens usando o ImageMagick.
E eu precisava de algo que fizesse exatamente isso:
- Converter tudo em
.webp; - Redimensionar as imagens para
2000pxx2000px; - Colocar a Marca D’água do madebyromeo;
- Ter opção para converter para
.jpge converter as imagens sem colocar a marca d’água.
E assim eu fiz. E posso dizer uma coisa: O ImageMagick não é complicado. Ele apenas não é familiar para nós, meros mortais.
Funcionamento do Script
O Script pode receber alguns argumentos, nesses modos aqui:
-
./fennecConvert imagem1.jpg: Converte todas as imagens que foram repassadas. Aqui, o Script converte, redimensiona e salva na pasta de saída; -
./fennecConvert imagem1.jpg -w: Com o-w, o Script adiciona uma Marca d’água na imagem. Ela deve ser configurada no arquivo~/.config/fennecTools/fennecConvert, com a opção “watermark=”; -
./fennecConvert imagem1.webp -j: Já com o-j, o Script define o formato de saída como.jpgao invés do.webpou do que está no arquivo de configuração. Fiz isso por necessidade pessoal; -
./fennecConvert imagem1.jpg -sf: E com o-sf, o Script define a pasta de saída na pasta em que ele está sendo executado. Isso é útil para imagens em que quero converter e que não quero que fique na pasta de saída; -
./fennecConvert -c: Já com o-c, o Script apenas exibe as variáveis que estão sendo carregadas e que serão usadas para uso do Script.
E esse script pode ser configurado com um arquivo em ~/.config/fennecTools/fennecConvert, com esse formato aqui:
format="webp"
output="$HOME/Imagens/[01] Made by Romeo/[03] Convertidos"
size="2000x2000"
watermark="$HOME/Imagens/[01] Made by Romeo/[06] Logos/Marca D'agua.png"
E a dependência principal desse Script é o ImageMagick para a conversão das imagens e como opcional, o notify-send para as Notificações.
Documentando o Código
Como em todos os Scripts que eu já publiquei por aqui, decidi explicar como ele funciona. Mas já posso adiantar que é um dos Scripts que eu mais gostei de fazer, com o poder de ser colocado no botão direito nos arquivos do Thunar e que pode receber várias imagens de uma vez.
O Começo do Script
Como todo Script, começa com aquela shebang: #!/usr/bin/env bash. E depois, com a localização do arquivo de configuração e uma função com uma pequena tela de boas-vindas e gostei desse toque.
#!/usr/bin/env bash
config="$HOME/.config/fennecTools/fennecConvert"
welcome () {
echo -e "\nfennecConvert 1.0.0 \nWritten by Rapoelho\n"
}
E logo em seguida, uma função um pouco mais útil do que a anterior: Notificações. Eu fiz isso, pois eu ficava sem saber quando a conversão terminou. Assim como no inSANE, eu fiz essa função de forma que, se o notify-send não existisse no sistema, o Script pudesse prosseguir.
notify () {
if ! [ -z "$(command -v notify-send)" ]; then
notify-send -a "fennecConvert" -i insert-image "Mission accomplished!" "Image converted successfully!"
fi
}
Depois, uma função para carregar as configurações padrão e que tem algumas variáveis: format para o formato padrão, output para a pasta de saída, size para o tamanho e watermark para a marca d’água.
loadDefaultConfig () {
format="webp"
output="$(xdg-user-dir PICTURES)/fennecConvert"
size="2000x2000"
watermark=""
}
Com isso, vem mais uma função: A que checa a pasta onde os arquivos que foram convertidos foram colocados. Basicamente, essa função verifica se a pasta existe e se não existir, a cria.
checkFolder () {
echo -e "## Checking Output Folder: $output\n"
if ! [ -d "$output" ]; then # Verificando se a pasta existe
mkdir "$output" # Se não existe, criar a pasta
fi
}
E por fim, coloquei a possibilidade desse Script usar um arquivo de configuração para poder usar outras variáveis que não as padrões e assim, eu poder distribuir esse Script em outros sites.
Essa função começa carregando as variáveis padrão, depois ela verifica se o arquivo de configuração existe em ~/.config/fennecTools/fennecConvert. Se existe, ela carrega o arquivo e as variáveis são substituídas pelas do arquivo de configuração.
loadUserConfig () {
loadDefaultConfig
if [ -e "$config" ]; then
echo -e "## Loading Configuration File..."
source $config
fi
}
E com isso, passamos para o Loop Principal.
Loop Principal
Agora, é a estrela do Script. Tudo o que está assim, ficou contido na função main, onde seriam os comandos básicos para processar cada um dos arquivos. Começando primeiro com o tratamento do nome dos arquivos.
Primeiro, o Script exibe o nome do Arquivo, depois usa o basename para extrair o nome do arquivo e o outputFile é montado com o caminho de saída que foi definido na variável output, depois trata o nome do arquivo com o echo "${file%%.*}" para retirar a extensão do arquivo e por fim, adicionando a extensão que foi definida na variável format.
echo -e "\n## File: $1"
file="$(basename "$1")"
outputFile="$output/$(echo "${file%%.*}").$format"
Depois, começa a conversão dos arquivos. O arquivo aqui é convertido. Simplesmente isso.
echo -e "### Converting to $format"
magick "$1" "$outputFile"
Depois, o ImageMagick pega o arquivo convertido no passo anterior e o redimensiona. Aqui é usado o \> para apenas reduzir o tamanho da imagem. E o arquivo de saída aqui, é o mesmo.
echo -e "### Resizing to $size"
magick "$outputFile" -resize $size\> "$outputFile"
Depois, vamos para a Marca D’água. Optei por fazer isso ser opcional e que isso seria uma sinalização de que, se fosse verdadeira, a marca d’água seria aplicada, com uma opacidade de 80%, no canto inferior direito.
if [[ $applyWatermark == "true" ]]; then
echo -e "### Applying the Watermark"
magick composite -dissolve 80% -gravity southeast "$watermark" "$outputFile" "$outputFile"
fi
Para terminar o pipeline de conversão, mais um comando do ImageMagick. Enquanto usava esse Script, acabei percebendo uma coisa: As fotos mudavam a orientação delas. Com isso, acabei encontrando um comando que corrige isso.
echo -e "### Correcting the image orientation..."
magick "$outputFile" -auto-orient "$outputFile"
E por fim, o Loop chama a função de Notificação, para avisar que a conversão do arquivo foi finalizada.
notify
Inicializando algumas coisas
Depois da função do Loop Principal, é onde o Script realmente inicializa algumas coisas. Aqui, ele chama a função que faz a tela de boas-vindas.
welcome
Depois, é verificado se o arquivo /tmp/imagelist existe. E se ele existe, o Script excluí o arquivo para deixar tudo limpo para o próximo uso.
if [ -e /tmp/imagelist ]; then
rm /tmp/imagelist
fi
E por fim, o Script chama a função que carrega o arquivo de configuração e a que checa a pasta em que os arquivos serão salvos.
loadUserConfig
checkFolder
Separando os Argumentos
Aqui é onde o Script fica interessante. Eu realmente queria que esse Script pudesse aceitar vários arquivos de uma vez, e sendo assim, eu tive que usar o $@, onde passa toda a lista de argumentos que foi passado ao Script. Com isso, começa um laço for, com essa linha:
for argu in "$@"; do
Que basicamente significa: Para cada argumento no que foi passado para o Script, faça isso. Depois, começa uma cadeia de if, onde é separado o que é arquivo e o que são opções para o Script.
if [ -f "$argu" ]; then
printf "%s\n" "$argu" >> /tmp/imagelist
elif [ "$argu" == "-w" ]; then
applyWatermark="true"
elif [ "$argu" == "-j" ]; then
format="jpg"
elif [ "$argu" == "-sf" ]; then
output="$(pwd)"
elif [[ "$argu" == "-c" ]]; then
loadUserConfig
echo -e "## Options \n - Size: $size \n - Format: $format \n - Output Folder: $output \n - Watermark: $watermark \n"
exit 0
fi
A primeira coisa que é verificada é, se aquele argumento é um arquivo. Isso é testado pela opção -f do if, e se for verdadeiro, a saída é jogada para o arquivo /tmp/imagelist.
if [ -f "$argu" ]; then
printf "%s\n" "$argu" >> /tmp/imagelist
E o restante, são opções para o Script. Começando pela opção -w, que é a que ativa a marca d’água na imagem. Aqui, a variável applyWatermark é marcada como true e isso será usado no Loop Principal.
elif [ "$argu" == "-w" ]; then
applyWatermark="true"
Depois, vem a opção -j, que é a que faz com o que o Script converta as imagens para jpg. Aqui a variável padrão definida na função loadDefaultConfig é sobrescrita.
elif [ "$argu" == "-j" ]; then
format="jpg"
Depois, temos a opção -sf. Aqui, o que muda é a variável output, que é alterada para a pasta em que o Script está sendo executado, sobrescrevendo a pasta padrão que foi definida pela função loadDefaultConfig.
elif [ "$argu" == "-sf" ]; then
output="$(pwd)"
E por fim, a opção -c. Basicamente, ele chama a função que carrega as configurações, exibe cada uma das variáveis e encerra o script.
elif [[ "$argu" == "-c" ]]; then
loadUserConfig
echo -e "## Options \n - Size: $size \n - Format: $format \n - Output Folder: $output \n - Watermark: $watermark \n"
exit 0
E quando todos os argumentos repassados para o Script acabam, o laço for termina com essa linha.
done
Juntando Tudo
E por fim, o Script junta tudo. Começando pela lista de opções definidas, em que é exibido um resumo do que está sendo executado. Claro, que se a variável applyWatermark for true, irá aparecer qual é a marca d’água que será aplicada. Também é mostrada a lista de imagens.
echo -e "## Options \n - Size: $size \n - Format: $format \n - Output Folder: $output"
if [[ $applyWatermark == "true" ]]; then
echo " - Apply Watermark: $watermark"
fi
echo -e "\n## Image List"
cat /tmp/imagelist
E por fim, um laço while. Esse laço pega cada uma das linhas do arquivo /tmp/imagelist e executa o Loop Principal usando aquela imagem como entrada.
while IFS= read -r imagem; do
main "$imagem"
done < /tmp/imagelist
E assim, termina esse Script.
Concluindo…
Definitivamente, o XnConvert é mais um programa que irei riscar das minhas listas de Pós-Instalação, pois o ImageMagick basta, sendo esse canivete suíço que ele é.
E outra coisa que esse Script me trouxe, foi um aprendizado. Consegui fazer ele receber múltiplos arquivos, consegui simplificar o carregamento de arquivos de configurações (e talvez, eu possa aplicar isso no inSANE) e esse acabou sendo o meu primeiro Script que fiz para usar com o Thunar.
E realmente, é muito bom poder substituir algo, que ou não está funcionando direito ou que é excessivamente complexo, por Scripts mais simples e que eu entendo o que está acontecendo. Acho que o meu momento é esse: de Simplicidade, daquela que realmente funciona.