Search code examples
ffmpeg

How to rotate an image overlay in ffmpeg around the image center?


I'm using ffmpeg to scale, rotate and overlay an image on a video. I'm able to rotate the image by the desired angle but the overlay ends up being moved both vertically and horizontally from the expected position.

The commands I've tried and their corresponding outputs are shown below. Command 1 gives the expected output, 2 and 3 do not.

How can I modify my commands in general, to rotate the overlay image around the image center, to get the expected output?

Command 1

ffmpeg -i graphpaper.mp4 -i arrow.png -y -filter_complex [1:v]scale=w=364:h=370[overlay0];[overlay0]rotate=a=0:c=none:ow=rotw(0):oh=roth(0)[rotate0];[0:v][rotate0]overlay=x=419:y=168[output0] -map [output0] sample-overlay-on-graph-paper.mp4

Command 2

ffmpeg -i graphpaper.mp4 -i arrow.png -y -filter_complex [1:v]scale=w=364:h=370[overlay0];[overlay0]rotate=a=0.8017360589297406:c=none:ow=rotw(0.8017360589297406):oh=roth(0.8017360589297406)[rotate0];[0:v][rotate0]overlay=x=419:y=168[output0] -map [output0] sample-overlay-on-graph-paper.mp4

Command 3

ffmpeg -i graphpaper.mp4 -i arrow.png -y -filter_complex [1:v]scale=w=364:h=370[overlay0];[overlay0]rotate=a=5.493783719179012:c=none:ow=rotw(5.493783719179012):oh=roth(5.493783719179012)[rotate0];[0:v][rotate0]overlay=x=419:y=168[output0] -map [output0] sample-overlay-on-graph-paper.mp4

Links to input files:


Solution

  • create graphpaper

    ffmpeg -lavfi "
    color=white:1280x720:d=5,
    drawgrid=0:0:25:25:0x7fffff,
    drawgrid=0:0:100:100:0x00ffff
    " -c:v ffv1 -g 1 "graphpaper.mkv"
    

    create arrow.png

    ffmpeg -lavfi "
    color=green:400x400,format=argb,
    geq=r=0:a='
     if(lt(Y,H/2-10)
    ,if(lt(X,W/2),if(between(X,W/2-Y,W/2+14-Y),255),if(between(X,W/2-14+Y,W/2+Y),255))
    ,if(lt(Y,H/2)
    ,if(lt(X,W/2),if(between(X,W/2-Y,W/2-90),255),if(between(X,W/2+90,W/2+Y),255))
    ,if(lt(Y,H-10)
    ,if(between(X,100,110)+between(X,W-110,W-100),255)
    ,if(between(X,100,W-100),255))))'
    " -frames 1 "arrow.png"
    

    overlay 2 times with different angles

    ffmpeg -i graphpaper.mkv -i arrow.png -filter_complex "
    [1:v]pad='hypot(iw,ih)':ow:-1:-1:color=black@0,split[v1][v2];
    [v1]rotate=0:c=none[r1];
    [v2]rotate=PI/4:c=none[r2];
    [0:v][r1]overlay=300-w/2:200-h/2[r1];
    [r1][r2]overlay=300-w/2:200-h/2
    " out.mp4
    

    300 and 200 are position of the center of rotation of the image