ffmpeg - zoompan causing stretching - ffmpeg

I have two images as input, both are 1600x1066. I am vertically stacking them. Then I am drawing a box and vertically stacking that box under both of the image. Inside of the box I write text, then I output a video that is 1080x1920. Everything works well, until I use zoompan to zoom in on the images, I get a weird behavior (see images included below). basically all input images including the box stretchs (shrink) vertically and no longer fit the entire height of the video which is 1920.
The command (removed some drawtext commands from it):
-filter_complex
"color=s=1600x1066:color=blue, drawtext=fontfile=font.otf: text='My Text':fontcolor=white: fontsize=30: x=50: y=50[box];
[0]scale=4000x4000,zoompan=z='min(zoom+0.0015,1.5)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=125:s=1600x1066[z0];
[1]scale=4000x4000,zoompan=z='min(zoom+0.0015,1.5)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=125:s=1600x1066[z1];
[z0][z1][box]vstack=inputs=3"
How do I fix this? I want to zoom in without stretching the images.
Video before using zoompan: https://i.stack.imgur.com/kTBto.jpg
Video after using zoompan: https://i.stack.imgur.com/7faNn.png

The problem was the scaling done before the zoompan ("scale=4000x4000") to remove the jiggly zoom effect. the scaling ration was not equal to the ratio of the image.
Ratio of image: 1600/1066 = 1.5
Ratio of scaling: 4000/4000 = 1
So scaling had to be changed to 6000/4000 = 1.5, which solved the problem.

Related

How to crop and scale correctly with FFMPEG?

I'm trying to remove the TOP AND BOTTOM black bars of a video.
Image sample from video
What i'm trying to achieve
The video itself is 1280x720 16:9, but the portion that's image information is at 4:3 since it's been captured from a VHS. I want to somehow stretch it until the top bars disappear without deforming the image. I don't care about the left and right bars.
I tried using crop and scale with no luck.
By using this code the top and bottom black bars disappeared on VLC when on normal screen but when going Full Screen the bars appeared again.
ffmpeg -i test.avi -filter:v "crop=1280:670" output_video.mp4
I thought it had something to do with the Scale of the video but honestly every scale code I tried to use deformed the image a lot.
I hope someone can help me, fairly new to FFMPEG but really enjoying it this far.
I got your image, resized it to 720p, made a 30 second video to test.
In my example I've also cropped the edges (left/right) because as #LordNeckbeard mentioned, when they hit the side of your screen, they may prevent the top/bottom of the video from reaching the top/bottom of the screen, which will again, look like black bars at the top/bottom, whether they are there or not.
This worked for me:
ffmpeg -y -hide_banner -i "test.avi" -filter:v "crop=iw-400:ih-40,scale=960:720" -pix_fmt yuv420p output_video.mp4
Quick explanation:
crop=iw-400:ih-40
Cropping 400 from the input width (iw) (2x200 left/right)
Cropping 40 from the input height (ih) (2x20 top/bottom)
You can cut a little more off if you want a 'crisper' edge.
scale=960:720
Scaling the video slightly to bring it back to your original 720p, the 960 is to keep it at a nice 4x3 ratio.
This scaling is not needed, your preference.
Let me know if it worked for you.

ffmpeg delogo works not good when delogo at boundary

I am trying using ffmpeg delogo filter to hide the logo, but I found when the logo is appears at boundary, delogo filter seems works not good. please check following images.
I also read a bit of source, seems the algorithm need subtract 1 pixel boundary. in the second image, the delogo result is looks strange, bottom is white. I want to make it invisible, is it possible?
thanks
Try
ffmpeg -i video
-filter_complex
"[0]split[m][b];
[b]crop=iw:144:0:174,vflip[a];
[m][a]vstack,delogo=794:689:134:40:1,crop=iw:720:0:0" out.mp4
The video is split in two. The 2nd feed is cropped to the bottom 20% but ending at a height just above the logo. This is then flipped and vertically stacked with the main stream. delogo is applied making sure that the height of the logo covers the whole logo. Then the excess portion at the bottom is cropped off.
Result:

FFMPEG set ZxY width and height thumbnail while keeping aspect ratio with padding

I have been searching Stack Overflow for code to create thumbnails using FFmpeg.
But the options I've come across either result in distorted thumbnails when using the -s 100x100 and a specific frame, or only correctly scale one side of the image when using -vf 100:-1. This is an issue for me as all thumbnails need to be the same size.
Is there a way to achieve both a set height/width and maintain a consistent aspect ratio, such as filling in blank spaces with black boxes?
https://trac.ffmpeg.org/wiki/Scaling%20(resizing)%20with%20ffmpeg
Sometimes there is a need to scale the input image in such way it fits into a specified rectangle, i.e. if you have a placeholder (empty rectangle) in which you want to scale any given image. This is a little bit tricky, since you need to check the original aspect ratio, in order to decide which component to specify and to set the other component to -1 (to keep the aspect ratio). For example, if we would like to scale our input image into a rectangle with dimensions of 320x240, we could use something like this:
ffmpeg -i input.jpg -vf scale="'if(gt(a,4/3),320,-1)':'if(gt(a,4/3),-1,240)'" output_320x240_boxed.png

Resize to a specific width and height using ffmpeg

I need to generate thumbnails for videos, automatically. I cannot predict the format of the video, but I need the thumbnail to be 220x120 pixels, always. Using -s 220x120 produces a weird stretch, just like -vf "scale=220:120". I'd like the stretching to be uniform, either cutting away top and bottom if the video is too high or adding black borders.
This is an example using a picture, same filter can be applied to video:
ow=220
oh=120
ffmpeg -i foo.png \
-vf "scale=max($ow\,a*$oh):max($oh\,$ow/a),crop=$ow:$oh" bar.png
Regardless of aspect ratio, this will:
scale down until width or height fits "the box"
crop down the other until it fits as well
The commas inside needs to be escaped so they aren't interpreted as filter separators.
§ Crop
§ Scale

ffmpeg resize down larger video to fit desired size and add padding

I'm trying to resize a larger video to fit an area that I have. In order to achieve this I calculate first the dimensions of the resized video so That it fits my area, and then I try to add padding to this video so that the final result will have the desired dimension, keeping the aspect ratio as well.
So let's say that I have the original video dimensions of 1280x720 and to fit my area of 405x320 I need first to resize the video to 405x227. I do that. Everything is fine at this point. I do some math and I find out that I have to add 46 pixels of padding at the top and the bottom.
So the padding parameter of the command for that would be -vf "pad=405:320:0:46:black". But each time I run the command I get an error like Input area 0:46:405:273 not within the padded area 0:0:404:226.
The only docs for padding that I found is this http://ffmpeg.org/libavfilter.html#pad.
I don't know what I'm doing wrong. Anyone had this problem before? Do you have any suggestions?
try -vf "scale=iw*min(405/iw\,320/ih):ih*min(405/iw\,320/ih),pad=405:320:(405-iw)/2:(320-ih)/2"
Edit to clarify what's going on in that line: you are asking how to scale one box to fit inside another box. The boxes might have different aspect ratios. If they do, you want to fill one dimension, and center along the other dimension.
# you defined the max width and max height in your original question
max_width = 405
max_height = 320
# first, scale the image to fit along one dimension
scale = min(max_width/input_width, max_height/input_height)
scaled_width = input_width * scale
scaled_height = input_height * scale
# then, position the image on the padded background
padding_ofs_x = (max_width - input_width) / 2
padding_ofs_y = (max_height - input_height) / 2
Here is a generic filter expression for scaling (maintaining aspect ratio) and padding any source size to any target size:
-vf "scale=min(iw*TARGET_HEIGHT/ih\,TARGET_WIDTH):min(TARGET_HEIGHT\,ih*TARGET_WIDTH/iw),
pad=TARGET_WIDTH:TARGET_HEIGHT:(TARGET_WIDTH-iw)/2:(TARGET_HEIGHT-ih)/2"
Replace TARGET_WIDTH and TARGET_HEIGHT with your desired values. I use this to pull a 200x120 padded thumbnail from any video. Props to davin for his nice overview of the math.
Try this:
-vf 'scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:x=(640-iw)/2:y=(480-ih)/2:color=black'
According to FFmpeg documentation, the force_original_aspect_ratio option is useful to keep the original aspect ratio when scaling:
force_original_aspect_ratio
Enable decreasing or increasing output video width or height if
necessary to keep the original aspect ratio. Possible values:
disable
Scale the video as specified and disable this feature.
decrease
The output video dimensions will automatically be decreased if
needed.
increase
The output video dimensions will automatically be increased if
needed.

Resources