Como recortar imagens e vídeos com FFmpeg
Use o filtro crop do FFmpeg para manter uma parte retangular de uma imagem ou de cada quadro de vídeo.
Por exemplo, crop=200:200:50:50 mantém uma região de 200×200 que começa a 50 pixels da borda esquerda e a
50 pixels do topo. A seguir, você vai recortar um JPEG e um MP4, conferir as dimensões deles e
aplicar o recorte de imagem a um diretório com Bash.
Prepare o FFmpeg e seus arquivos
Execute os exemplos no Bash, no macOS ou no Linux. Instale uma build que contenha ffmpeg, ffprobe
e o encoder libx264 usando os links por plataforma da
página de download do FFmpeg. Os comandos foram testados com o
FFmpeg 9.0.1 no macOS e 6.1.1 no Ubuntu 24.04.
Confira sua instalação:
ffmpeg -version && ffprobe -version && ffmpeg -hide_banner -h encoder=libx264
O último comando deve listar os recursos do encoder. Se ele informar um encoder desconhecido,
instale uma build com libx264 antes de continuar.
Coloque um JPEG já na orientação correta chamado input.jpg e um MP4 chamado input.mp4 no seu diretório de trabalho.
O exemplo de imagem precisa de pelo menos 250×250 pixels; o recorte fixo de vídeo precisa de pelo menos
1280×720. Os exemplos de vídeo pressupõem um vídeo SDR comum, com pixels quadrados e sem metadados
de rotação. Recortar gravações HDR ou anamórficas exige tratamento adicional de cor ou de proporção de tela.
Os comandos de arquivo único usam -y: executá-los novamente substitui os arquivos de saída nomeados.
Escolha outro nome de saída para manter um resultado anterior e mantenha os nomes de saída diferentes
dos de entrada. -nostdin desativa a interação pelo teclado para que os comandos também funcionem sem supervisão.
Consulte as opções de linha de comando do FFmpeg.
Escolha o retângulo de recorte
A sintaxe do filtro é crop=width:height:x:y. As coordenadas começam em (0,0) no canto superior
esquerdo; x aumenta para a direita e y, para baixo. O recorte remove os pixels fora do
retângulo sem redimensionar o conteúdo dele.
Para um retângulo que fique dentro da entrada, use dimensões positivas e deslocamentos não negativos,
com x + width não maior que a largura da entrada e y + height não maior que a altura dela.
Confira esses limites você mesmo: o FFmpeg pode ajustar um deslocamento fora dos limites para que o retângulo
caiba, em vez de informar um erro.
Você pode omitir x e y para centralizar o recorte. Em entradas com subamostragem de croma, o filtro normalmente
arredonda coordenadas e dimensões para baixo, até a grade de subamostragem. Os exemplos abaixo usam valores
pares para o formato 4:2:0 comum. A
referência do crop do FFmpeg documenta esses padrões e
a opção exact para recortes que precisam de coordenadas ímpares.
Recorte de imagens com FFmpeg
Recorte o retângulo descrito acima e salve-o como cropped.png:
ffmpeg -hide_banner -nostdin -y -pattern_type none -i input.jpg \
-vf "crop=200:200:50:50" -frames:v 1 -update 1 cropped.png
-frames:v 1 grava uma única imagem. O PNG evita outra codificação JPEG com perdas após o recorte.
-pattern_type none faz o nome do arquivo de entrada ser interpretado literalmente, e -update 1 faz o mesmo com
o nome do arquivo de saída. Essas opções também importam quando um nome de arquivo contém %03d, que
o FFmpeg, caso contrário, trataria como padrão de sequência de imagens. Esses comportamentos estão documentados
nas opções de entrada de imagem
e nas opções de saída de imagem.
Confira as dimensões da saída com ffprobe:
ffprobe -v error -select_streams v:0 -show_entries stream=width,height \
-of csv=p=0:s=x cropped.png
Isso deve exibir 200x200. Abra também o PNG: as dimensões sozinhas não dizem se
você manteve o objeto pretendido.
Recorte de vídeos com FFmpeg
Mantenha a região de 1280×720 do canto superior esquerdo em cada quadro de input.mp4:
ffmpeg -hide_banner -nostdin -y -i input.mp4 \
-map 0:v:0 -map '0:a:0?' -vf "crop=1280:720:0:0" \
-c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 128k cropped.mp4
A saída contém vídeo H.264 e, quando houver, a primeira faixa de áudio codificada em AAC.
O ? entre aspas torna o mapeamento de áudio opcional, então entradas sem áudio também funcionam. Faixas
de vídeo adicionais, faixas de áudio adicionais e legendas são omitidas. Consulte a
documentação de mapeamento de fluxos.
O recorte exige decodificar e recodificar o vídeo, então -c:v copy não pode ser combinado
com esse filtro. -crf 18 é uma configuração de qualidade para a codificação H.264 com perdas.
-pix_fmt yuv420p seleciona saída 4:2:0, que exige largura e altura pares com esse encoder.
Recorte um quadrado centralizado
Para vídeos em paisagem ou em retrato, escolha a menor dimensão da entrada e arredonde-a para baixo até um número par:
ffmpeg -hide_banner -nostdin -y -i input.mp4 \
-map 0:v:0 -map '0:a:0?' -vf "crop=w='trunc(min(iw,ih)/2)*2':h=ow" \
-c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 128k square.mp4
Aqui, iw e ih são as dimensões da entrada, e ow é a largura de recorte calculada.
Omitir x e y centraliza o quadrado, sujeito ao arredondamento pela grade de croma descrito
acima. Uma entrada de 1920×1080 produz 1080×1080 pixels. Este é um recorte central fixo, então um
objeto perto de uma borda ainda pode ser cortado.
Verifique o vídeo gerado
Inspecione as dimensões e os codecs usando as
entradas selecionadas do ffprobe:
ffprobe -v error -show_entries stream=codec_type,codec_name,width,height \
-of json cropped.mp4
Espere um fluxo de vídeo h264 com largura 1280 e altura 720, além de um fluxo aac se
a entrada tiver áudio. Substitua cropped.mp4 por square.mp4 para conferir o recorte quadrado.
Reproduza o resultado para conferir o enquadramento e o som ao longo de todo o clipe.
Recorte imagens JPEG em lote
Salve isto como crop-images.sh e execute bash crop-images.sh a partir do diretório que contém
seus JPEGs. Ele processa os arquivos não ocultos terminados em .jpg minúsculo nesse diretório,
usando o mesmo recorte de 200×200 em (50,50). Cada entrada precisa atender ao mínimo de 250×250 para
esse retângulo.
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob
images=(./*.jpg)
if (( ${#images[@]} == 0 )); then
printf '%s\n' 'No .jpg files found.' >&2
exit 1
fi
mkdir ./cropped
for image in "${images[@]}"; do
name=${image##*/}
ffmpeg -hide_banner -loglevel error -nostdin -y \
-pattern_type none -i "$image" -vf "crop=200:200:50:50" \
-frames:v 1 -update 1 "./cropped/${name%.jpg}.png"
done
O script exige um diretório cropped novo: se ele já existir, mkdir falha e
o script para antes de processar qualquer coisa. Guarde os resultados desse diretório e escolha
um novo diretório de saída no script para outra execução. As saídas são PNGs em um subdiretório,
então não podem virar entradas na próxima execução.
As aspas e o prefixo ./ lidam com espaços e hifens iniciais nos nomes de arquivo; as opções
de imagem lidam com padrões literais de porcentagem nos dois lados. Um diretório vazio gera um
erro. Se o FFmpeg falhar em uma imagem ilegível ou pequena demais para o recorte, o script para;
os arquivos já gravados permanecem em cropped, então inspecione os resultados parciais antes de tentar de novo.
