スポンサード リンク

Subtitle フィルタで文字または文字の縁の色を透明にする方法

AviSynth 2.5.8 RC1 のヘルプを見ていて気づいたのですが、Subtitle フィルタで文字の色(text_color)と文字の縁の色(halo_color)の透明度を設定することが可能になっています。更新履歴を見ると、AviSynth 2.5.8 から追加される機能のようです(2.5.8 RC1 で動作確認済み。それ以前については不明)。

設定方法は簡単です。これまでは 16 進数を使って「$RRGGBB」という形式で R(赤)、G(緑)、B(青)をそれぞれ指定していました。透明度を指定したい場合は、さらに「$AARRGGBB」というように A の部分に 16 進数でアルファ値を指定すればよいのです。

たとえば、

$00000000

なら、完全に不透明な黒に、

$FF000000

なら、完全に透明になります。

もう少し例を挙げます。

# クリップの生成
BlankClip(1, 320, 240, color=$eaeaea)
# halo_color=$ff0000 と同じ
Subtitle("transparent?", y=0, size=48, text_color=$336699, halo_color=$00ff0000)
# 文字の縁の色を半透明に
Subtitle("transparent?", y=40, size=48, text_color=$336699, halo_color=$80ff0000)
# 文字の縁の色を完全な透明に
Subtitle("transparent?", y=80, size=48, text_color=$336699, halo_color=$ffff0000)
# 文字の色も縁の色も半透明に
Subtitle("transparent?", y=120, size=48, text_color=$80336699, halo_color=$80ff0000)
# 文字の色を透明に、縁の色を不透明に
Subtitle("transparent?", y=160, size=48, text_color=$ff336699, halo_color=$00ff0000)

サンプル画像

なお、従来通り「$RRGGBB」という形式で指定した場合は、完全に不透明な色(つまりこれまでと同じ)になります。

Subtitle フィルタにとって -1 は魔法の値

Subtitle フィルタで x と/または y の値を -1 に設定すると自動的に中央揃えされるという話。少し古いネタですが、整理していたら出てきたのでメモ。

IanB 氏曰く、この -1 は「魔法の値」だそうです。

What is causing a glitch at frame 294 in my script? - Doom9's Forum

Originally Posted by documentation

... The parameters x and y can be set to -1 to automatically calculate and use the horizontal or vertical center coordinate.

Ahhhgggg magic values

このことは Subtitle フィルタのマニュアルにも書かれていますし、Subtitle 単独で使用する場合にはすぐに気づくと思います。ただし、Subtitle を Animate などと組み合わせて使用する際には、意図せず x と/または y に -1 が入ってしまうケースもあるかと思います(逆に偶然 -1 が入らないケースもあるでしょう)。

BlankClip(5, 320, 240)
Animate(0, 4, "Subtitle", "'-1' is a magic value.",2,-1, "'-1' is a magic value.",-2,-1)

このスクリプトを VirtualDub や AvsP を使ってコマ送りしてみてください(5 フレームしかないので、再生すると一瞬で終わってしまいます)。ちょうど x の値が -1 になるフレーム 3 で、テキストが急に中央に移動します。y の値は -1 で固定させていますので、そちらでも -1 がどういう働きをするかを確認できると思います。

対処法

いくつか対処法が考えられます。

  • メッセージの頭にスペースを付け足して、-1 よりも大きい値をスキップし、直接 -2 から開始する(What is causing a glitch at frame 294 in my script? - Doom9's Forum より IanB 氏のアイデア)
  • ラッパー関数を用意して、x または y が -1 の場合は、0 または -2 にする(完全な解決にはなりませんが、簡単な次善の策として)。
  • Animate ではなく、Overlay と ConditionalReader の組み合わせにする(ConditionalReader で ol_x_offset/ol_y_offset を定義して移動させる)。
  • 絶対に -1 にならないようにする(例えば、大きめのクリップを用意して最小値が -1 より大きくなるようにし、あとでいらない部分を Crop する、など)。

対処例

2 番目のラッパー関数を使う方法を示します。

まず次のような関数を用意します。

# 簡単な Wrapper 関数の例
function SubtitleWrapperTest(clip input, string moji, int x, int y) {
    # x が -1 なら 0 に設定、それ以外ならそのまま
    x = (x == -1) ? 0 : x # 0 でなく -2 にしてもよい
    # y が -1 なら 0 に設定、それ以外ならそのまま
    y = (y == -1) ? 0 : y # 0 でなく -2 にしてもよい

    # 新しい x と y を Subtitle の引数に指定
    output = input.Subtitle(moji, x, y)

    # output 返す
    return output
}

ここでは簡略化のために size や font などの設定は省略しています。よって、このままでは実用的ではありません。Animate との併用時にはフォントなどは固定でしょうから、関数の中でデフォルト値を設定してしまってもいいでしょう。

BlankClip(5, 320, 240)
Animate(0, 4, "SubtitleWrapperTest", "'-1' is a magic value.",2,-1, "'-1' is a magic value.",-2,-1)

Subtitle の代わりに用意した関数を指定します。コマ送りしてみると、フレーム 3 で少し停止したような印象を受けるかもしれません。しかし、中央揃えされるよりはいいでしょう。

これはあくまでも回避策ですので、他の方法も試してみてください。ちなみに mojimoji 関数: テキストの移動と拡大縮小の mojimoji ではこのラッパー関数を利用する方法を、mojimojiOvr では 3 番目の Overlay と ConditionalReader を併用する方法を使っています。

関連記事

ラッパー関数について

Overlay フィルタの最適化

possible Overlay() optimisation? - Doom9's Forum より sh0dan 氏の投稿。少し古いネタですが、整理していたら出てきたのでメモ。

前提

  • 質問者の Mug Funky 氏は、Overlay がすべてのフレームで画像(PNG)全部をレンダリングして遅いので、これを最適化する方法を尋ねています。
  • Overlay フィルタの内部形式は、YUV 4:4:4(YV24)。入力クリップはいったんこの形式に変換されます。
  • AviSynth v2.6(2008-03-19 現在、公式なリリースはありません)から YV24 がサポートされる予定です。

sh0dan 氏の回答

possible Overlay() optimisation? - Doom9's Forum

Well - overlay converts the image to yv24 before it applies clipping, but it will only convert the mask, if any part of the image is visible.(Overlay はクリッピングを適用する前にその画像を YV24 に変換します。しかし、もしその画像のどの部分も見えているのなら、マスクのみを変換します。)

Convert your images to YV12. The YV12 -> YV24 is much faster - especially for the mask.(画像を YV12 に変換してください。YV12 -> YV24 はずっと高速です - とりわけマスクに関しては。)

If you need to maintain chroma, use v2.6, as you can use YV24 natively.(もし色差を保持する必要があるのなら、YV24 をネイティブに使用できる v2.6 を使ってください。)

まとめ

  • v2.5x では、Overlay に渡す前に YV12 に変換しておくと、より高速になる。
  • v2.6 では YV24 にするという選択肢も。

といった感じでしょうか。

リサイズフィルタのクロップ機能とリサイズ+クロップの違い

Is there a chromatic aberration filter? - Doom9's Forum より IanB 氏の投稿。少し古いネタですが、整理していたら出てきたのでメモ。

エッジの扱い

Is there a chromatic aberration filter? - Doom9's Forum

...resize(1440,1080,1,1,-1,-1)

versus(と)

...resize(1442,1082).crop(1,1,-1,-1)

Are not exactly the same. The boundary conditions in the resizer are different. In the first case the edge row of pixels are not used in the output image, in the second they are. A very minor point.(は、正確には同じではありません。リサイザでの境界線の状態が異なります。最初のケースではピクセルのエッジの列は出力画像では使用されません。2 番目のケースでは使用されます。非常に些細なことではありますが。)

データ型の違い

Is there a chromatic aberration filter? - Doom9's Forum

Also the cropping factors on the resizers are floating point numbers so you can get subpixel adjustment if required.(またリサイザのクロッピング係数は浮動小数点数です。このため、必要ならサブピクセル補正が得られます。)

その他(マニュアルより)

  • エッジの近くにノイズがあるような場合、リサイズフィルタのクロップ機能ではこれを拡大させる恐れがある。
  • 処理速度にも若干の差がある。

SubtitleとAnimateを組み合わせてテキストを移動させる

2008-04-08 追記: この方法には問題があります。詳しくは、Subtitle フィルタにとって -1 は魔法の値を参照してください。

にーやんのブログ :: Project N: 024 - 文字雨(Animateフィルタを使う)のように、Subtitle フィルタと Animate フィルタを組み合わせれば、テキストを移動させたり、拡大縮小したりすることができます。簡単な例をあげながら、これをもう少し説明したいと思います。

# ソースクリップ
BlankClip(200, 320, 240, fps=29.97)

BlankClip フィルタを使って空のクリップ(200frames, 320x240, 29.97fps)を作成します。今回は、これをソースクリップとして使用します。

font = "MS Pゴシック" # フォント
size = 36
text_color = color_lightpink # フォントの色($FFB6C1)
halo_color = color_hotpink # 文字の縁の色($FF69B4)

フォントの色や大きさなどを指定しておきます。フィルタの中で直接指定してもOKです。その場合は、下記のスクリプトの font, size, text_color, halo_color となっているところを変更します。

color_lightpink と color_hotpink は、AviSynthで使用出来る色のプリセットです。プリセット値は、AviSynth と一緒にインストールされる colors_rgb.avsi(plugins フォルダの中にあります)の中で設定されています。colors_rgb.avsi は、オートローディング機能で、自動的に読み込まれます。10 進数か 16 進数を使って指定してもかまいません。

# 右から左へ移動
Animate(0, 29, "Subtitle",
\ "キタ━(゚∀゚)━!",320,100,0,29,font,
\ "キタ━(゚∀゚)━!",-200,100,0,29,font)

Subtitle フィルタの引数のうち、x だけが変化していることに注意してください。0 フレームのときは x = 320、29 フレームのときは x = -200 の位置に配置されます。日本語(2バイト文字)なので、それに対応しているフォントを指定する必要があります。

# 下から上へ移動
Animate(30, 59, "Subtitle",
\ "萌えーっ!!",70,240,30,59,font,size,text_color,halo_color,
\ "萌えーっ!!",70,-50,30,59,font,size,text_color,halo_color)

今度は y の値だけが変化しています。

# 拡大
Animate(60, 89, "Subtitle",
\ "萌えーっ!!",160,120,60,89,font,1,text_color,halo_color,
\ "萌えーっ!!",-40,80,60,89,font,96,text_color,halo_color)

size を変化させることで、テキストの拡大や縮小も可能です。ただし x と y を固定にすると、左上から右斜め下へと拡大(縮小の場合は、その逆)するように見えてしまいます。これを防ぐために、x と y の値も変化させています(適当)。

Subtitle フィルタには、テキストの配置に関する align という引数もあります。今回は align は使用しませんでしたが、これを組み合わせてみてもいいかもしれません。

# 左上から右下へ移動
Animate(90, 159, "Subtitle",
\ "/⌒ヽ  ちょっと通りますね",-200,0,90,159,font,16,$FFFFFF,$000000,
\ "/⌒ヽ  ちょっと通りますね",350,150,90,159,font,16,$FFFFFF,$000000)
Animate(90, 159, "Subtitle",
\ "/ ´_ゝ`)",-210,18,90,159,font,16,$FFFFFF,$000000,
\ "/ ´_ゝ`)",340,168,90,159,font,16,$FFFFFF,$000000)
Animate(90, 159, "Subtitle",
\ "|    /",-210,36,90,159,font,16,$FFFFFF,$000000,
\ "|    /",340,186,90,159,font,16,$FFFFFF,$000000)
Animate(90, 159, "Subtitle",
\ "| /| |",-208,54,90,159,font,16,$FFFFFF,$000000,
\ "| /| |",342,204,90,159,font,16,$FFFFFF,$000000)
Animate(90, 159, "Subtitle",
\ "// | |",-216,72,90,159,font,16,$FFFFFF,$000000,
\ "// | |",334,222,90,159,font,16,$FFFFFF,$000000)
Animate(90, 159, "Subtitle",
\ "U  .U",-222,90,90,159,font,16,$FFFFFF,$000000,
\ "U  .U",328,240,90,159,font,16,$FFFFFF,$000000)

x と y の両方を変化させることで、斜め方向への移動も可能です。

# 上から下へ移動
Animate(160, 199, "Subtitle",
\ "萎え . . . orz",70,-50,160,199,font,36,color_olivedrab,
\ "萎え . . . orz",70,240,160,199,font,36,color_olivedrab)

これは下から上への移動の逆です。

FadeOut(30)

最後はフェードアウト。

これを 1 つの AVSファイルにまとめて、MPEG-1 形式の動画に変換してみました。

サンプル動画(MPEG-1, 424KB)

あまりなめらかとは言えないかもしれませんが、一応、動いています。

Page 1 of 5: 1 2 3 4 5 »