[FFmpeg-user] Stretch/Scale only center of overlay image

Hans Carlson forbyta at gmx.com
Thu Feb 13 03:36:50 EET 2020


Is it possible to stretch/scale only the center part of an overlay image?

I don't mean the middle section of a video, I mean only the center part of 
a single image (png) that will be overlayed onto a background, such that 
the left and right sides are relatively unchanged, but the center of the 
image is stretched to fit the new size.

To further explain... I have a background image with a bunch of text lines 
of varying length.  I want to overlay an oval (actually a rounded 
rectangle) over some text as a highlight.  Since all the text parts are 
different lengths, I'll either need to create a separate overlay image for 
each one OR create one standard overlay image and "stretch/squeeze" it to 
fit each section of text.  I'd prefer to create only a single overlay 
image.

The problem is, when I try to stretch/squeeze my rounded rectangle (using 
scale) the ends either get stretched too much or squeezed too much 
depending if I need to scale up or down.  What I'd like to see is the ends 
look the same (or close to) the original overlay image and only the center 
part is stretched/squeezed.

Is there some filter I can use instead of or in addition to "scale" that 
will do something like this?

Below is an example that illustrates the issue using the ImageMagick 
"convert" command to generate the background and highlight images and 
ffmpeg to overlay the highlight on the background.

What you'll notice is the highlight around the shortest text has the ends 
squeezed too much and the highlight around the longest text has the ends 
stretched too much.


Create a background image with 4 text lines:

   $ convert -size 720x480 xc:black -font DejaVu-Sans -pointsize 20 -fill white -draw "text 200,100 'not scaled at all'" -draw "text 200,200 'short'" -draw "text 200,300 'middle size line'" -draw "text 200,400 'very very long line with extra words" background.png

Create a rounded rectangle highlight for the overlay:

   $ convert -size 200x50 xc:none -fill transparent -stroke green -strokewidth 5 -draw "roundrectangle 10,5 190,45 20,20" highlight.png

Overlay the highlight on each text line and "stretch/squeeze" (using 
scale) to fit the text width:

   $ ffmpeg -loop 1 -i background.png -loop 1 -i highlight.png -codec:v mpeg2video -b:v 16384k -bufsize 4096k -maxrate 30000k -filter_complex '[1:0]scale=70:in_h[o1];[1:0]scale=190:in_h[o2];[1:0]scale=430:in_h[o3];[0:0][1:0]overlay=x=180:y=70[v1];[v1][o1]overlay=x=190:y=170[v2];[v2][o2]overlay=x=182:y=270[v3];[v3][o3]overlay=x=166:y=370' -t 5 -f vob example.mpg
   ffmpeg version N-96725-g13dc90396d Copyright (c) 2000-2020 the FFmpeg developers
     built with gcc 9 (GCC)
     configuration:
     libavutil      56. 40.100 / 56. 40.100
     libavcodec     58. 68.102 / 58. 68.102
     libavformat    58. 38.100 / 58. 38.100
     libavdevice    58.  9.103 / 58.  9.103
     libavfilter     7. 75.100 /  7. 75.100
     libswscale      5.  6.100 /  5.  6.100
     libswresample   3.  6.100 /  3.  6.100
   Input #0, png_pipe, from 'background.png':
     Duration: N/A, bitrate: N/A
       Stream #0:0: Video: png, gray(pc), 720x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
   Input #1, png_pipe, from 'highlight.png':
     Duration: N/A, bitrate: N/A
       Stream #1:0: Video: png, pal8(pc), 200x50, 25 fps, 25 tbr, 25 tbn, 25 tbc
   Stream mapping:
     Stream #0:0 (png) -> overlay:main
     Stream #1:0 (png) -> scale
     Stream #1:0 (png) -> scale
     Stream #1:0 (png) -> scale
     Stream #1:0 (png) -> overlay:overlay
     overlay -> Stream #0:0 (mpeg2video)
   Press [q] to stop, [?] for help
   Output #0, vob, to 'example.mpg':
     Metadata:
       encoder         : Lavf58.38.100
       Stream #0:0: Video: mpeg2video (Main), yuv420p, 720x480, q=2-31, 16384 kb/s, 25 fps, 90k tbn, 25 tbc (default)
       Metadata:
         encoder         : Lavc58.68.102 mpeg2video
       Side data:
         cpb: bitrate max/min/avg: 30000000/0/16384000 buffer size: 4096000 vbv_delay: N/A
   frame=  125 fps=0.0 q=2.0 Lsize=     378kB time=00:00:04.92 bitrate= 629.4kbits/s speed=11.9x
   video:373kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.427849%


More information about the ffmpeg-user mailing list