Ffmpeg uses rotate to solve the problem of four corners being cut after rotation – use pad filter to add a larger background

Time:2022-5-15
  • Let’s start with a normal usage scenario. I put a PNG image on the video and use the overlay filter to solve it.
  • At this time, I want to rotate the PNG. At this time, the four corners may be cut off. How to solve this problem? After pad, you need to move the image to the center of the layer, so that when the layer rotates, the image will not be cut off. I take the following command as a column. For convenience of naming, I take PHP code as an example
/**
     *Notes: move left
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     *Relevant parameters corresponding to @ param $data array
     *@ param $video string corresponds to the video to be processed
     * @param $base_ Dir string the directory where the file is located
     */
    public function move_left($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //Download gif material
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        $px=$data['size_x']*2;// Pad is an image twice as big as the original size. Why twice? As a square, the diagonal is the longest line, with a length of about 1.414 and a root sign of two. Double pad is fully applicable and easy to calculate. It is emphasized that PNG here is a square, and X represents the transverse, that is, the span
        $py=$data['size_y']*2;// Y stands for longitudinal, i.e. height
        $nx=$data['coord_x']-$data['size_x']/2;//,
        $ny=$data['coord_y']-$data['size_y']/2;//,
        //Rotation angle and size, position
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:[email protected][v1];\
 [v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN):\
 x=%s-min((t-%s),%s)*%s :shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //It is necessary to calculate the sliding speed of Y and move to the end within the specified time
        $length=self::B_LEFT-$data['coord_x'];
        $speed=120;// Sliding speed
        $time_move=$length/$speed;
        $png_shell=sprintf($png_shell,$png,$video,$data['size_x'],$data['angle'],$data['bt'],$data['et'],

            $data['coord_y'], self::B_LEFT, $data['bt'], $time_move,$speed, $des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);// Todo keeps the video temporarily and deletes it later
        return $des_video_name;
    }

Drawing instructions, for example, we want to place a picture like this

Ffmpeg uses rotate to solve the problem of four corners being cut after rotation - use pad filter to add a larger background

image.png

After the pad completes the image, if the PNG position on the left is not specified, the default is the 0, 0 position of the pad

Ffmpeg uses rotate to solve the problem of four corners being cut after rotation - use pad filter to add a larger background

image.png


However, if a selection occurs at this time, the three corners will be cut off, so we need to put PNG at the center of gravity of pad layer. These parameters can be specified in pad

Ffmpeg uses rotate to solve the problem of four corners being cut after rotation - use pad filter to add a larger background

image.png

However, there will be a problem after this designation. The coordinates of PNG have changed. What should we do at this time? We need to change the coordinate position corresponding to the pad layer, because PNG is offset by half the side length to the lower right corner, so we can move half the side length to the upper left corner of the whole pad layer

Ffmpeg uses rotate to solve the problem of four corners being cut after rotation - use pad filter to add a larger background

image.png