Skip to content

Instantly share code, notes, and snippets.

@Jagua
Last active January 2, 2016 20:29
Show Gist options
  • Save Jagua/8357638 to your computer and use it in GitHub Desktop.
Save Jagua/8357638 to your computer and use it in GitHub Desktop.
#
# for VapourSynth (Core r22, API r3)
#
# vim:filetype=python.vapoursynth foldmethod=marker et:
# coding: utf-8
# スマイルプリキュア(※文字化け対策)
################################################################
#
# Import library
#
from ctypes import *
import vapoursynth as vs
core = vs.get_core(threads = 2)
width, height = 320, 240
################################################################
#
# Utility
#
def linear(x0, y0, x1, y1, n, frames):
x = x0 + (x1 - x0) * n / frames
y = y0 + (y1 - y0) * n / frames
return int(x), int(y)
def bspline(x0, y0, x1, y1, x2, y2, n, start, end):
if end == start:
x, y = x2, y2
else:
t = (n - start) / (end - start)
x = (1 - t)**2 * x0 + 2 * t * (1 - t) * x1 + t**2 * x2
y = (1 - t)**2 * y0 + 2 * t * (1 - t) * y1 + t**2 * y2
return int(x), int(y)
################################################################
#
# Main
#
def main():
# 適当な長さ,大きさのクリップを用意.
clip_blank = core.std.BlankClip(width = width, height = height, \
format = vs.RGB24, fpsnum = 30, length = 450, color = [80, 152, 90])
clip = clip_blank
text = '{\\an5}{\\pos(160, 120)}東方輝針城'
clip_sub1 = core.assvapour.Subtitle(clip, text, \
style = 'sans-serif,36,' \
+ '&H000000FF,&H00FFFFFF,&H00000000,&H00000000,' \
+ '-1,0,0,0,100,100,0,0,1,2,0,8,10,10,5,1')
text = '{\\an5}{\\pos(160, 120)}月下の犬歯'
clip_sub2 = core.assvapour.Subtitle(clip, text, \
style = 'sans-serif,36,' \
+ '&H000000FF,&H00FFFFFF,&H00000000,&H00000000,' \
+ '-1,0,0,0,100,100,0,0,1,2,0,8,10,10,5,1')
clip = clip_sub1[0]
def mf_f(n, f):
fsub1 = f[0].copy()
fsub2 = f[1].copy()
fblank = f[2].copy()
for p in range(fsub1.format.num_planes):
w = fblank.get_stride(p)
s1 = fsub1.get_read_ptr(p).value
s2 = fsub2.get_read_ptr(p).value
d0 = fblank.get_write_ptr(p).value
# フォントの点灯ドットの座標を総て配列化.
# FIXME: ここじゃなくてもっと前の段階で用意しとくべきかな
src = []
dst = []
for y in range(fblank.height):
for x in range(fblank.width):
if c_ubyte.from_address(int(s1 + x + y * w)).value != 0:
src.append([x, y])
if c_ubyte.from_address(int(s2 + x + y * w)).value != 0:
dst.append([x, y])
# 第一点灯ドット数が,第二点灯ドット数より少ない場合は
# 第一点灯ドットの配列を擬似ループさせて水増す
if len(src) < len(dst):
for i in range(len(dst)):
point = dst[i]
x1, y1 = point[0], point[1]
point = src[i % len(src)]
x0, y0 = point[0], point[1]
x_, y_ = bspline(x0, y0, x0 + 20, y0 - 30, x1, y1, n, 40, 120)
if x_ >= 0 and x_ < fblank.width and y >= 0 and y < fblank.height:
# FIXME: 以下の色データ 0xf0 はサンプル元の色を使うべき
memset(c_void_p(int(d0 + x_ + y_ * w)), 0xf0, 1)
else:
# 第一点灯ドット数が,第二点灯ドット数より多い場合は
# 第二点灯ドットの配列を擬似ループさせて水増す
for i in range(len(src)):
point = src[i]
x0, y0 = point[0], point[1]
point = dst[i % len(dst)]
x1, y1 = point[0], point[1]
x_, y_ = bspline(x0, y0, x0 + 20, y0 - 30, x1, y1, n, 40, 120)
if x_ >= 0 and x_ < fblank.width and y >= 0 and y < fblank.height:
# FIXME: 以下の色データ 0xf0 はサンプル元の色を使うべき
memset(c_void_p(int(d0 + x_ + y_ * w)), 0xf0, 1)
return fblank
clip_base = clip
clip_blank = core.std.BlankClip(clip)
selector = mf_f
clip = core.std.ModifyFrame(clip = clip_base, \
clips = [clip_sub1[0], clip_sub2[0], clip_blank], selector = selector)
return clip
################################################################
clip = main()
clip = core.text.Text(clip, "th14")
clip = core.resize.Bicubic(clip, format = vs.YUV420P8)
clip.set_output()
enable_v210 = True
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment