0

i have a mkv file and its resolution is 1280x720. when i calculated the crop using Handbrake, it shows that i need to crop 40 from top and 30 from bottom. So far i know how to crop equal amount from top and bottom, but i cannot understand how to specify that the crop values for top and bottom are different

so far i tried crop=in_w:in_h-80 which cuts 40 from top and 40 from bottom, but i want to cut only 30 from bottom

thank you

1

3 Answers 3

3

After two days of looking for an answer to this question, I found out the logic behind it and I'll share it here, because this topic looks as the best place for it, I hope it helps people understand it more easily through my explanation than through all the other explanations I found with Google on many sites and forums.

So I wanted to crop different number of rows - 20 from the top and 10 from the bottom - of a video file, and I used this command:

ffmpeg -i input.file -vf crop=iw:ih-30:0:10 -c:v av1_nvenc -c:a copy output.file

The logic of the crop=iw:ih-30:0:10 is as follows:

  • iw - input width of the video, which stays the same as the original

  • ih - input height of the video, which we want to cut

  • 30 - the total number of rows we want to remove

  • 0 - I don't know why we have to input this, but we just have to

  • 10 - the number of rows, which we want to cut from the bottom

1
1

This being the first result I got from searching, I decided to use WYSIWYG answer and write a bash script that simplifies this significantly (at least for me):

#!/bin/bash
if [[ -z $6 ]];then
        printf "Usage:\n"
        printf "        $0 [input file] [output file] [top crop] [bottom crop] [left crop] [right crop]\n"
        printf "Any edges you do not want to crop, enter 0.\n"
        printf "For example, to crop 10 pixels from the top, 11 from the botom, none from the left and 8 from the right:\n"
        printf "        $0 input-file.jpg output-file.jpg 10 11 0 8\n"
        exit 2
fi

inpFile=$1
outFile=$2
tCrop=$3
bCrop=$4
lCrop=$5
rCrop=$6
let xCrop=$lCrop+$rCrop
let yCrop=$tCrop+$bCrop

ffmpeg -i $inpFile -vf crop=iw-$xCrop:ih-$yCrop:$lCrop:$tCrop $outFile
exit $?

Run this script without any arguments to get a how-to printout.

When you specify your crop values for each edge, it does the math for you. Saves you from having to add up your top & bottom / left & right crops.

A full explanation for the ffmpeg's crop formatting is below. Each of these values represent what they should be in the output file.

crop=w:h:x:y

w = width.

h = height.

x = X (horizontal) position the output should start at, from the left. AKA how many pixels to lose from the left.

y = Y (vertical) position the output should start at, from the top. AKA how many pixels to lose from the top.

As you can see, width and height support "iw" and "ih" respectively to keep those values from the input file. And, you can perform math on those within the command. That's where the "iw-30" comes from in WYSIWYG's answer.

2
  • Thank you so much! This one works and is the correct answer! Commented Sep 16 at 9:17
  • I love how you break down the different components now you can easily and flexibly set which sides to crop. Commented Sep 16 at 9:25
0

Based on https://ffmpeg.org/ffmpeg-filters.html#toc-crop

should it be crop=in_w:in_h-70:0:40

1
  • can you please explain how you came to that solution. Commented Dec 10, 2021 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.