2012年9月21日金曜日

VapourSynthでプレビュー

とりあえず現時点ではVapourSynthでクリップのプレビューが出来るエディタ等はないので、間に合わせで書いてみました。

#vsshow.py

import vapoursynth as vs
from ctypes import *
from PIL import Image

def show(core, clip, frame_number, vflip=1):
    format = clip.format.id
    width = clip.width
    height = clip.height
    if format == vs.GRAY16:
        clip = core.resize.Point(clip, width, height, vs.GRAY8)
    if format != vs.GRAY8 and format != vs.RGB24:
        clip = core.resize.Bicubic(clip, width, height, vs.COMPATBGR32)

    format = clip.format.id
    planes = range(clip.format.num_planes)
    frame = clip.get_frame(frame_number)
    data = [(frame.get_read_ptr(p), frame.get_stride(p)) for p in planes]
    buff = [b'\0' * data[p][1] * height for p in planes]
    for p in planes:
        memmove(buff[p], data[p][0], data[p][1] * height)

    if format == vs.COMPATBGR32:
        mode, src = 'RGBA', 'BGRA'
    else:
        mode, src = 'L', 'L'
    img = [Image.frombytes(mode, (width, height), buff[p], 'raw', src,
                           data[p][1], vflip) for p in planes]
    if len(planes) != 1:
        img = Image.merge('RGB', (img[2], img[0], img[1]))
    else:
        img = img[0]

    img.show()

使い方
>>> import vapoursynth as vs
>>> import vsshow
>>> core = vs.Core()
>>> core.std.LoadPlugin('vsavsreader.dll')
>>> clip = core.avsr.Eval('ColorBars()')
>>> vsshow.show(core, clip, 1234)

こんな感じで指定したフレーム番号のフレームがプレビューできます。
vsshow.pyはvapoursynth.pydと同じ場所に置いておけばいいです。
ビューワーにはPIL(Python Imaging Library)の仕様上、.bmpファイルに関連付けされているアプリケーションが使われます(MSペイントだったりPicasaだったりMangameeyaだったり)。
なお、Python3用のPILは、こちらからDLしてインストールして下さい。
フレームがYUVの場合のRGB変換はVS内蔵のswscaleが使われる都合上、BT601のlimitted-range限定です。
色々ひどいと我ながら思いますが、ないよりはマシくらいのおおらかな気持ちで使いましょう。

だれかPySideあたりでもっといいの書いてくれないかしら。


Pythonはいろいろ不慣れでこれだけでも苦労しました(おかげでPythonの学習自体ははかどりましたが)。
Twitterでnu774氏(qaacの中の人)に色々アドバイス頂いたおかげで随分助かりました。

0 件のコメント:

コメントを投稿