高価な動画編集ソフト(premiere とか)がなくても動画作れちゃうんだぜ!
動画なんて,パラパラ漫画と同じ要領で作ればいいわけで.フレームごとに convert とかで画像作って mencoder でエンコードすれば,どんなムービーでも作れる.動画作成頻度が低くて,高価なソフトを買いたくないし使い方を覚えたくない場合の処方箋を紹介.
ある画像から別の画像にフェードする動画生成スクリプト †
ImageMagick に含まれる composite コマンドを使って,じょじょにある画像から別の画像にフェードする画像群を作り,それらを mencoder でエンコードする.このスクリプトさえあれば,黒い画像からフェードインさせたり,白い画像にフェードアウトしたりする動画が簡単に生成できる.
ソース (fade-avi) †
#!/bin/bash
usage="usage: fade-avi FROM_IMG TO_IMG OUT_AVI [options]
options:
-fstep <1-100> : FADE_STEP = fading speed. larger value is faster (default:1)
-fclones <0-inf> : FROM_CLONES = how many copies are put at the beginning? (default:0)
-offset <0-100> : OFFSET = initial value of the fading level (default=0)
-fps <1-1000> : FPS of the movie (default:50)
-help : show this"
source ~/lib/bash/option-parser.sh
set_single_opts help
parse_opts "$@"
if [ `opt help 0` -eq 1 ]; then
echo "$usage"
exit 1
fi
if [ ${#fargs[@]} -ne 3 ] ;then
echo "invalid arguments."
echo "$usage"
exit 1
fi
img_from=${fargs[0]}
img_to=${fargs[1]}
out_file=${fargs[2]}
fade_step=`opt fstep 1`
from_clones=`opt fclones 0`
offset=`opt offset 0`
fps=`opt fps 50`
tmp_dir=/tmp/fadeavi$$
# generating fading images...
mkdir $tmp_dir
index=1
if [ $from_clones -gt 0 ];then
basefile=$tmp_dir/frame`seq -w $index 10000 1000`.jpg
convert -quality 100 $img_from $basefile
index=$(($index+1))
for i in `seq 2 1 $from_clones`; do
echo -n " $i"
cp $basefile $tmp_dir/frame`seq -w $index 10000 1000`.jpg
index=$(($index+1))
done
fi
tmp_img_from=/tmp/fadeavi$$-from.jpg
convert -quality 100 $img_from $tmp_img_from
for i in `seq $offset $fade_step 100`; do
echo -n " $i"
composite -dissolve $i -gravity South $img_to $tmp_img_from -matte \
$tmp_dir/frame`seq -w $index 10000 1000`.jpg
index=$(($index+1))
done
rm $tmp_img_from
echo ""
# generating movie encoded with avi...
mencoder "mf://$tmp_dir/frame*.jpg" -mf fps=$fps -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=2400 -o $out_file
rm -r $tmp_dir
echo "$out_file is generated."
実行には ImageMagick と mencoder が必要.また,コマンドラインオプションパーサ(~/lib/bash/option-parser.sh)が必要.
使い方 †
fade-avi 画像1 画像2 出力ファイル.avi [オプション]
のように使うと,画像1から画像2にフェードする動画(出力ファイル.avi)が生成される.
オプション:
- fstep <1-100> : フェードのステップ.大きい程速くフェードする.(default:1)
- fclones <0-inf> : 動画の最初で,画像1を何フレーム繰り返すか (default:0)
- offset <0-100> : フェードレベルの初期値 (default=0)
- fps <1-1000> : 動画のFPS (default:50)
- help : ヘルプを表示
サンプル †
Stanford BunnyからLennaにフェードさせた動画を生成.
fade-avi Stanford_Bunny.png lena_std.tif bunny_to_lenna.avi
タイトル文字列から画像にフェードする動画生成スクリプト †
タイトル文字列を表示させて,それがじょじょに消えて行くと同時に,指定した画像がフェードインしてくる動画を生成するスクリプト.
ソース (title-fade-avi) †
#!/bin/bash
usage="usage: title-fade-avi TITLE_STR TO_IMG OUT_AVI [options]
options:
-tcolor <r,g,b> : title color (default:255,0,0)
-tsize <1-inf> : title font size (default=24)
-bgcolor <r,g,b> : background color (default:255,255,255)
-fstep <1-100> : FADE_STEP = fading speed. larger value is faster (default:2)
-tdisptime <0-inf> : TITLE_DISPLAY_TIME = how many frames is the title displayed in? (default:50)
-tpos <x,y> : title position (default:0,0)
-fps <1-1000> : FPS of the movie (default:50)
-help : show this"
source ~/lib/bash/option-parser.sh
set_single_opts help
parse_opts "$@"
if [ `opt help 0` -eq 1 ]; then
echo "$usage"
exit 1
fi
if [ ${#fargs[@]} -ne 3 ] ;then
echo "invalid arguments."
echo "$usage"
exit 1
fi
title=${fargs[0]}
img=${fargs[1]}
out_file=${fargs[2]}
title_color=`opt tcolor 255,0,0`
title_size=`opt tsize 24`
bg_color=`opt bgcolor 255,255,255`
fade_step=`opt fstep 2`
title_display_time=`opt tdisptime 50`
title_pos=`opt tpos 0,0`
fps=`opt fps 50`
tmp_dir=/tmp/titlefadeavi$$
img_size=`identify -format "%wx%h" $img`
# generating fading images...
mkdir $tmp_dir
index=1
if [ $title_display_time -gt 0 ];then
basefile=$tmp_dir/frame`seq -w $index 10000 1000`.jpg
convert -quality 100 -size $img_size xc:"rgb($bg_color)" \
-font Helvetica -pointsize $title_size -fill "rgb($title_color)" \
-gravity Center -draw "text $title_pos '$title'" \
$basefile
index=$(($index+1))
for i in `seq 2 1 $title_display_time`; do
echo -n " $i"
cp $basefile $tmp_dir/frame`seq -w $index 10000 1000`.jpg
index=$(($index+1))
done
fi
for i in `seq 255 -$fade_step 0`; do
echo -n " $i"
alpha=`echo "scale=5;$i/255"|bc`
convert -quality 100 $img -size $img_size xc:"rgba($bg_color,$alpha)" -composite -compose Overlay \
-font Helvetica -pointsize $title_size -fill "rgba($title_color,$alpha)" \
-gravity Center -draw "text $title_pos '$title'" \
$tmp_dir/frame`seq -w $index 10000 1000`.jpg
index=$(($index+1))
done
echo ""
# generating movie encoded with avi...
mencoder "mf://$tmp_dir/frame*.jpg" -mf fps=$fps -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=2400 -o $out_file
rm -r $tmp_dir
echo "$out_file is generated."
実行には ImageMagick と mencoder が必要.また,コマンドラインオプションパーサ(~/lib/bash/option-parser.sh)が必要.
使い方 †
title-fade-avi タイトル文字列 画像1 出力ファイル.avi [オプション]
のように使うと,タイトル文字列から画像1にフェードしていく動画(出力ファイル.avi)が生成される.
オプション:
- tcolor <r,g,b> : タイトル文字列の色 (default:255,0,0)
- tsize <1-inf> : フォントサイズ (default=24)
- bgcolor <r,g,b> : 背景色 (default:255,255,255)
- fstep <1-100> : フェードのステップ.大きい程速い (default:2)
- tdisptime <0-inf> : タイトル文字列を何フレーム表示させるか (default:50)
- tpos <x,y> : タイトル文字列の位置 (default:0,0)
- fps <1-1000> : 動画のFPS (default:50)
- help : ヘルプを表示
サンプル †
Lenna という文字列からLennaにフェードさせた動画を生成.
title-fade-avi -tsize 48 "Lenna" lena_std.tif lenna.avi
そのほかの技術 †
もっと多彩な動画を †
convert コマンドを使えば,複数の画像をひとつの画像にまとめたり,文字列を配置したりできる.これをスクリプトで生成し,mencoder でエンコードすれば,自由に動画が作れる.(が,なかなか一般化したスクリプトを作りにくいので,個別にスクリプトを書く必要があるorz..)
動画を連結 †
mencoder mov1.avi mov2.avi mov3.avi \ -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=2400 -o all.avi
mov1.avi, mov2.avi, mov3.avi を連結した動画 all.avi を生成する.
動画を変換 †
ffmpeg -i all.avi -r 40 -b 400k all-d.mpg
all.avi (msmpeg4v2) を,フレームレートを40に,ビットレートを400kに下げ,mpeg1 でエンコードした動画 all-d.mpg に変換する.mencoder でも同様のことができるはずだが,mpeg1 への変換は mencoder より ffmpeg を使った方が安定して行えた(mencoder を使った場合,一部のプレーヤーで再生できないことがあった).