ImageMagickとFFMPEGで回転するロゴを作成します

この記事は、ビデオチャンネルのデザインを少し活性化したい人や、ヘッダーに示されているツールを使い始めたばかりの人にとって興味深いものです。 自信のあるユーザーが私の資料を補完することを願っています。



ロゴを復活させる方法を考えました。これをスポーツイベントのビデオに載せました。 20秒ごとに垂直軸を中心にロゴを回転させるというアイデアがありました。 その結果、私はこのようなものを手に入れたかったのです。







タスクを完了するには、imagemagickとffmpegがインストールされたシステムが必要です。 Imagemagickはbashを使用してコマンドを生成します。 bcユーティリティの使用を伴うもの bashの数学はかなり単純で、三角関数の計算は困難です。



たとえば、Pythonを使用すると、サインインとコサインが計算されるので、同じことがさらに簡単になります。



ビデオを作成するには、ロゴが完全な革命を起こすNフレームを作成し、それらをビデオファイルに変換します。



実際、回転は、次元の1つでの画像の連続的な圧縮と拡大です。 垂直軸を中心とした均一な回転の効果を得たい場合、画像の幅はサイン関数またはコサイン関数の値の倍数だけ変化します。



私たちにとっての初期状態はロゴがフルサイズで見えるため、画像の幅を変更するには、その幅に余弦を掛けます(ゼロの値は1に正確に等しくなります)。



これらの目的のための画像の回転は、4つの段階に分けることができます。

-画像が狭くなります。

-展開しますが、裏側で視聴者に向いています。

-ビューアーに戻るテーパー。

-元のサイズに拡大します。



基本的なフレームセットを形成します; 0〜90度回転するようにフレームを構築し、残りの270のフレームを少し変換して取得します。 サイクルは、それぞれ0〜360度ではなく、0〜90度です。



ロゴへのパスを記述してから、短い$ロゴでアクセスします。



logo=../../logo/Moto_Gymkhana_transparent.png
      
      





便宜上、ロゴの幅と高さに等しい変数を導入します。そのため、異なる画像に合わせてスクリプトを調整しやすくなります。



 width=842 height=595
      
      





ロゴが4分の1回転するフレームの数に等しい変数を取得しましょう。 回転角度を計算するステップを計算するために一度必要になります。



 Frames=15
      
      





ループでは、次のものが必要です。

-変数「n」で指定された角度だけ画像が回転したときの画像の幅を計算します。

-850x600などのサイズの空のキャンバスを作成します。

-幅が圧縮された画像を中央に追加します。



 for (( n=0; n<=90; n+=$(expr $(( 90/$Frames ))))) do oWidth=$(printf %.$2f $(echo "$width*(c($n*4*a(1)/180))+1" | bc -l)) convert -size 850x600 xc:transparent -background none \ \( -alpha set -channel A -evaluate add -60% $logo -geometry $oWidth\ x$height\! \)\ -gravity center -composite ./tmp/$n.png done
      
      







コードを部分的に分析しましょう。



特定の角度で画像の幅を計算します。



 oWidth=$(printf %.$2f $(echo "$width*(c($n*4*a(1)/180))+1" | bc -l))
      
      





このピースを右から左に分解する方が便利です。

「| bc -l」は、これがbcユーティリティによって計算されることを示します。

なぜなら 「bc」ユーティリティのコサインはラジアン単位で入力されますが、bashにはpiがありません。次の式を使用します。

c($ n * 4 * a(1)/ 180)-ここで

「C」はコサイン、

$ n-サイクルで変化する角度(度単位)。

(1)は、π/ 4に等しい単位のアークタンジェントです。 したがって、4 * a(1)は数字piを書き込む方法です。 ラジアンから度に移動するには、180で割ります。

したがって、「$ width *(c($ n * 4 * a(1)/ 180))」は、幅に角度「n」のコサインを掛けたものです。

この式の後に「+1」を追加すると、画像の幅が値0になりません。ImageMagickは、幅がゼロの画像を作成しようとすることを認識しません。

$(printf%。$ 2f $(echo "$ width *(c($ n * 4 * a(1)/ 180))+ 1" | bc -l))-特定の角度の幅の値を計算し、丸めて出力全体に。



 convert -size 850x600 xc:transparent -background none \ \( -alpha set -channel A -evaluate add -60% $logo -geometry $oWidth\ x$height\! \)\ -gravity center -composite ./tmp/$n.png
      
      





convert -size 850x600 xc:transparent -background none-背景なしでサイズが640x360の透明なキャンバスを作成します。



コマンドの後続部分は、シールドされた「\」括弧で囲まれているため、単独で実行されます。 これは重要です。そうしないと、サイズ変更がキャンバスに影響します。

-alpha set-透明度チャンネルを有効にします。

-channel A -evaluate add -60%-すべての画像ピクセルのチャンネルAの値に「-60%」を追加します。

$ロゴは画像へのパスです。

-geometry $ oWidth \ x $ height \! -画像のサイズを変更します。

「-geometry AxB」は画像のサイズを変更しますが、アスペクト比は保持します。 つまり 幅を縮小しようとすると、「幅x高さ」の比率を維持するために画像の高さも減少し、空の領域が上下に表示されます。

「-geometry AxB \!」 「幅x高さ」の比率を維持しようとする必要はありませんが、互いに独立して変更します。

-重力センター-中央に配置します。

-composite-画像を結合します。

./tmp/$n.png-ファイルを「tmp」フォルダーに保存し、変数「n」の現在の値に名前を付けます。



54度の角度からの眺め:







この参照画像セットから、将来のアニメーションの4つのフレームを作成します。



上から見たときにロゴを時計回りに回転させます。 画像にボリュームを追加するには、画像がフレームのどこで回転するかに応じて、右または左にシフトした「影」を追加します。 そして、ロゴが裏側で見る人に向けられているフレームに、左から右に画像を反映します。 同じフレームの「シャドウ」は元の画像の下には追加されませんが、ロゴの裏面の効果を作成するためにその上に追加されます。



ローテーションの第1四半期の式を詳細に検討します。 残りは類推によって理解されます。 最初との違いにのみ焦点を当てます。



 convert tmp/$n.png \ \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \)\ -background none -compose Src_Over -layers merge \ -gravity center tmp/logo$(expr $(( 1000+n ))).png
      
      







convert tmp / $ n.png-元の画像をベースとして使用します。



\(+ clone -background '#cccf' -shadow 100x8 + $ shadowShift-3 \)-影画像を傾けて作成します。

背景オプションで指定された色は、影の色を設定します。

影の不透明度(パーセント)とぼかしの程度は、「100x5」パラメーターで設定します。

元の画像に対するシャドウオフセットは、+ x + yに設定されます。 この例では、垂直シフトは一定(3ピクセル上)であり、水平シフトはshadowShift変数によって設定されます。

この変数の値は、元のフレームの垂直圧縮と同じ方法で計算します。 余弦ではなく、角度の正弦を取るだけです、なぜなら 角度ゼロでのシフトはゼロでなければなりません。



shadowShift = $(printf%。$ 2f $(echo "15 *(s($ n * 4 * a(1)/ 180))+ 1" | bc -l))

第1四半期と第2四半期では影を右にシフトする必要があるため、shadowShift値にプラス記号を、3番目と4分の1にマイナス記号を付けます。



-backgroundなし-compose Dst_Over -layers merge -gravity center -depth 8 tmp / logo $(expr $((1000 + n)))。png



ここで重要なオプションは-composeです。 どの画像を一番上に配置するかを設定します。

ターンの第1四半期では、ロゴ自体が一番上にあるため、Dst_Overです。 第2四半期と第3四半期には、Src_Over(影が一番上)が登録されます。



-layers merge -gravity center-レイヤーを結合し、中央に配置します。



tmp / logo $(expr $((1000 + n)))。png-tmpフォルダーにlogo +“ 1000 + value n”という名前で保存します。



名前は、フレーム名がアルファベット順にすぐにソートされるようなものであり、処理のためにそれらをffmpegに与えるのが便利でした。



第2四半期のフレームの場合、「1800-n」、3番目の「2000 + n」、4番目の「2800-n」になります。



第2四半期と第3四半期には、-flopオプションが表示されます-画像を左から右に反転します。 このため、ところで、シャドウオフセットの符号を反対に変更する必要があります。



ターンの4四半期すべてのコード:



 convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) \ -background none -compose Dst_Over -layers merge -gravity center -depth 8 tmp/logo$(expr $(( 1000+n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8-$shadowShift-3 \) \ -background none -compose Src_Over -layers merge -gravity center -flop tmp/logo$(expr $(( 1800-n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) \ -background none -compose Src_Over -layers merge -gravity center -flop tmp/logo$(expr $(( 2000+n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8-$shadowShift-3 \) \ -background none -compose Dst_Over -layers merge -gravity center tmp/logo$(expr $(( 2800-n ))).png
      
      







その結果、元のフレームからわずかな違いのある4つが取得されました。







次は、これらの画像からビデオを収集するための小さなものです。



 ffmpeg -pattern_type glob -i 'tmp/logo*.png' -pix_fmt argb -vcodec qtrle -r 30 rotatingLogo.mov
      
      





-pattern_type glob-コンソールから使い慣れた形式でフレームの名前のマスクを指定できます

-i 'tmp / logo * .png'-名前が「logo」で始まるtmpフォルダーからソースイメージデータとして取得します。

-pix_fmt argb-透明度のある画像形式を設定します。 ARGBの「A」は単なるアルファチャネルです

-vcodec qtrle-透明度をサポートするビデオのコーデックを設定します。 私が知っているもののうち、qtrleとpngです

-r 30-最終ビデオの周波数を30フレーム/秒に設定します。

rotation_logo.mov-「rotatingLogo.mov」として保存



これでコマンドを実行できます
 ffplay rotatingLogo.mov
      
      



そして結果を見てください:







結果のビデオの長さはわずか数秒です。 これらの作品の多くを一緒に互換性があります

これを行うには、同じffmpegを使用します。



ロゴが絶えず回転するのではなく、ときどきロゴが固定されたビデオを作成します。 記事の場合は、表示するときにローテーションを長く待つ必要がないように、3秒の長さにします。



 ffmpeg -loop 1 -pattern_type glob -i 'tmp/logo1000.png' -pix_fmt argb -vcodec qtrle -r 30 -t 3 stillLogo.mov
      
      





このコマンドにはオプション "-loop 1"が表示されます-入力画像シーケンス(この場合は1つのみ)を繰り返すようffmpegに指示し、オプション "-t 3"は最終ビデオの長さが3秒であることを示します。



固定および回転ロゴを使用してビデオを接着するには、接着する必要があるファイルのリストを含むファイルを作成します。 この場合、ファイルの20インスタンス:

 for (( i=0; i<20; i+=1 )) do echo file 'stillLogo.mov' >> list.txt echo file 'rotatingLogo.mov' >> list.txt done
      
      







このファイルを、トランスコード(-cコピー)ではなく、コーデックをコピーする命令とともにconcatフィルターの入力に渡します。



 ffmpeg -f concat -i list.txt -c copy logoWithRotation.mov
      
      











結果のロゴをビデオにオーバーレイするために残ります。

ロゴは非常に大きく、含まれています。 適用するときは、3倍に縮小します。



 ffmpeg -i video.mov -i logoWithRotation.mov \ -filter_complex "[1:0]scale=iw/2:ih/2[logo];[0:0][logo]overlay=shortest=1:x=20:y=500" \ -vcodec libx264 -crf 18 overlay.mov
      
      







ffmpeg -i video.mov -i logoWithRotation.mov-2つのビデオを入力として使用します。



-filter_complex-次を指定するfilter_complexを使用します。

[1:0] scale = iw / 3:ih / 3 [logo]-2番目のビデオからストリーム0を取得し(1カウントはゼロから始まります)、幅(iw-入力幅)と高さ(ih-入力高さ)を3回減らします。 「logo」という名前で渡します。



[0:0] [logo] overlay = shortest = 1:x = 20:y = 0-最初のビデオからストリーム0を取得し、ストリーム「ロゴ」をそれらの上に重ねます。

「最短= 1」-いずれかのスレッドの終わりに到達すると終了することを示します。

x = 20:y = 500-ビデオオーバーレイの左上隅の配置場所を示します。



-vcodec libx264 -crf 18-H264コーデックを使用します。 crfの後の値は、圧縮する量を示します。 0-圧縮なし。



overlay.mov-この名前で保存します。



結果を見る:



 ffplay overlay.mov
      
      














記事の図面とアニメーションは、同じツールを使用して作成されます。 記事に登場する順番:



 ffmpeg -i rotatingLogo.mov -filter_complex "[0:0]scale=iw/3:ih/3" rotatingLogo.gif montage tmp/54.png -geometry 300x200 result.png montage -mode concatenate -tile 2x2 tmp/logo1054.png tmp/logo1746.png tmp/logo2054.png tmp/logo2746.png -geometry 300x200 result.png ffmpeg -i logoWithRotation.mov -t 5.5 -filter_complex "[0:0]scale=iw/3:ih/3" logoWithRotation.gif
      
      










回転ロゴを作成するための最終スクリプト:



 logo=../../logo/Moto_Gymkhana_transparent.png Frames=15 width=842 height=595 mkdir tmp for (( n=0; n<=90; n+=$(expr $(( 90/$Frames ))))) do oWidth=$(printf %.$2f $(echo "$width*(c($n*4*a(1)/180))+1" | bc -l)) shadowShift=$(printf %.$2f $(echo "15*(s($n*4*a(1)/180))+1" | bc -l)) convert -size 850x600 xc:transparent -background none \( -alpha set -channel A -evaluate add -50% $logo -geometry $oWidth\ x$height\! \) -gravity center -composite -depth 8 ./tmp/$n.png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) -background none -compose Dst_Over -layers merge -gravity center -depth 8 tmp/logo$(expr $(( 1000+n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8-$shadowShift-3 \) -background none -compose Src_Over -layers merge -gravity center -flop tmp/logo$(expr $(( 1800-n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8+$shadowShift-3 \) -background none -compose Src_Over -layers merge -gravity center -flop tmp/logo$(expr $(( 2000+n ))).png convert tmp/$n.png \( +clone -background '#cccf' -shadow 100x8-$shadowShift-3 \) -background none -compose Dst_Over -layers merge -gravity center tmp/logo$(expr $(( 2800-n ))).png done ffmpeg -pattern_type glob -i 'tmp/logo*.png' -pix_fmt argb -vcodec qtrle -r 30 rotatingLogo.mov ffmpeg -loop 1 -pattern_type glob -i 'tmp/logo1000.png' -pix_fmt argb -vcodec qtrle -r 30 -t 3 stillLogo.mov rm list.txt for (( i=0; i<20; i+=1 )) do echo file 'stillLogo.mov' >> list.txt echo file 'rotatingLogo.mov' >> list.txt done ffmpeg -f concat -i list.txt -c copy logoWithRotation.mov
      
      







ロゴを3倍減らしたvideo.movファイルにオーバーレイします。



 ffmpeg -i video.mov -i logoWithRotation.mov -filter_complex "[1:0]scale=iw/3:ih/3[logo];[0:0][logo]overlay=shortest=1:x=20:y=500" -vcodec libx264 -crf 18 overlay.mov
      
      






All Articles