TCAX 字幕特效制作工具官方论坛 | ASS | TCAS | Python | Aegisub | Lua
标题:
[J]037_Gundam_Seed_OP3特效脚本 (附完整工程)
[打印本页]
作者:
milkyjing
时间:
2012-7-20 07:35:47
标题:
[J]037_Gundam_Seed_OP3特效脚本 (附完整工程)
说明:需要升级至少
TCAX 1.1.9 SP1
并添加
tcAudio模块
才可以正常执行本工程。
Gundam_Seed_OP3.rar
(5.91 MB, 下载次数: 4150)
2012-7-20 07:37:19 上传
下载次数: 4150
from tcaxPy import *
from util.gdiFont import *
from util.tcAudio import *
from util.magick import *
from pixLibs.ImageStone import *
def tcaxPy_Init():
global _Fs
global _FD # 一帧的持续时间, 约40毫秒
global Font # 首要字体
global FontOut # 字体边框
global FontOut2 # 字体边框2
global FontShad # 加粗字体
global GdiFontThin
_Fs = GetVal(val_FontSize)
_FD = 1000 / GetVal(val_FXFPS)
_FontFileName = GetVal(val_FontFileName)
_FaceID = GetVal(val_FaceID)
Font = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 0, False)
FontOut = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 4, True)
FontOut2 = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 2, True)
FontShad = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 4, False)
GdiFontThin = gfInitFont(GetVal(val_FontFaceName), _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), -2.5, False)
# 初始化tcAudio, 本例是一个典型的tcAudio模块用法
global channel
tcAudioInit()
channel = tcAudioOpen('op.mp3')
# 颜色表
global color_op
color_op = ((1, 0, 0), # red
(1, 1, 0), # yellow
(1, 0, 1), # pink
(0, 1, 0), # green
(0, 1, 1), # sky blue
(0, 1, 0), # green
(1, 1, 0), # yellow
(0, 1, 0), # green
(0, 0, 1), # blue
(1, 0, 1), # pink
(1, 0, 0)) # red
# 各种K值
global minK
global meanK
global maxK
kar = GetVal(val_KarTime)
lineNum = GetVal(val_nLines)
textNum = GetVal(val_nTexts)
minK = 2 * 60 * 100
maxK = 0
SumK = 0
for i in range(lineNum):
SumLineK = 0
for j in range(textNum[i]):
SumLineK += kar[i][j]
minK = min(minK, kar[i][j])
maxK = max(maxK, kar[i][j])
SumK += SumLineK / textNum[i]
meanK = SumK / lineNum
# 图片序列
global PIX_list
PIX_list = []
num = 30
for i in range(1, num, 2):
img_path = MakePath(5, i, 'images', 'list', 'img', '.png', 'sys')
img_size = 5 * _Fs - 20
PIX = ImagePix(img_path, img_size, 0)
PIX_list.append(PIX)
def tcaxPy_Fin():
FinFont(Font)
FinFont(FontOut)
FinFont(FontOut2)
FinFont(FontShad)
gfFinFont(GdiFontThin)
tcAudioFin()
def tcaxPy_Main(_i, _j, _n, _start, _end, _elapk, _k, _x, _y, _a, _txt):
ASS_BUF = [] # 保存ASS特效
TCAS_BUF = [] # 保存TCAS特效
##### 主要特效编写操作 ####
dx = _x - int((_a + GetVal(val_Spacing)) / 2 + 0.5) # 一个固定操作, 将an5的坐标转换为an7
dy = _y - int(_Fs / 2 + 0.5) # ASS特效默认采用an5坐标, TCAS特效则采用an7坐标
# 文字主体
PIX = TextPix(Font, _txt)
PIX_t0 = PixColorRGB(PIX, DecRGB('FFFFFF')) # 未增加内部填充
PIX = PixFromPoints(gfGetPoints(GdiFontThin, _txt))
PIX = PixColorRGB(PIX, DecRGB('111111'))
PIX_thin = PixBlur(PIX, 2) # 内部填充
PIX_t = CombinePixs(PIX_t0, PIX_thin) # 增加了内部填充的主体
# 边框主体
PIX = TextPix(FontOut, _txt)
PIX = PixColorRGB(PIX, DecRGB('000040'))
PIX_o = PixBlur(PIX, 6)
# 边框
PIX = TextPix(FontOut2, _txt)
PIX = PixColorRGB(PIX, DecRGB('AAAAAA'))
PIX_b = PixBlur(PIX, 4)
# 底色
PIX = TextPix(FontShad, _txt)
PIX = PixColorRGB(PIX, DecRGB('800080'))
PIX_s = PixBlur(PIX, 18)
# 混合
PIX = CombinePixs(PIX_s, PIX_o)
PIX = CombinePixs(PIX, PIX_b)
PIX_0 = CombinePixs(PIX, PIX_t0)
PIX_1 = CombinePixs(PIX, PIX_t)
# 一些时间的计算
T0 = 10 * _start - 12 * _FD + 1 * _j * _FD
T1 = T0 + 4 * _FD
T2 = 10 * _end + 5 * _FD - 2 * (_n - _j - 1) * _FD
T3 = T2 + 8 * _FD
# IN 入场方式 part1
img0 = pmgToImage(PIX_0)
num = 6
for i in range(num):
img = Image(img0)
img.motionBlur(0, (num - i) * 10, 0)
PIX = PixPos(pmgToPix(img), PIX_0[0][0], PIX_0[0][1])
ts0 = T0 + i * _FD
te0 = ts0 + _FD
tcas_main(TCAS_BUF, PIX, ts0, te0, dx, dy, 0)
# MAIN 存在方式 part1
ts1 = te0
te1 = 10 * (_start + _elapk)
tcas_main(TCAS_BUF, PIX_0, ts1, te1, dx, dy, 0)
# IN 入场方式 part2 种子填充算法应用
te_ret = SeedFill(TCAS_BUF, PIX_thin, T1, te1, dx, dy)
# EFT 表现方式
num = int(10 * _k / _FD + 0.5)
for i in range(num):
ts = te1 + _FD * i
te = ts + _FD
tcAudioSetPos(channel, tcAudioSec2Bytes(channel, ts / 1000)) # 设置音频文件指针位置为当前歌词
fft = tcAudioGetFFT(channel, 2048) # 获取音频FFT数据, 取样数为2048
bars = Spectrum(fft, _n, 50)
bar_pct = max(bars[0:len(bars)//2]) / 50
factor = 1 + LinearLines(minK, 0.15, meanK, 0.4, maxK, 0.5, _k) * Factor(i / num)
PIX = PixResizeF(PIX_1, PIX_1[1][0] * factor, 0)
PIX = BilinearFilter(PIX, dx, dy)
color = MakeRGB(bar_pct * 255 * color_op[_i][0], bar_pct * 255 * color_op[_i][1], bar_pct * 255 * color_op[_i][2])
if random() < 1 / 3:
color = MakeRGB(bar_pct * 255, bar_pct * 255, bar_pct * 255)
PIX = pstBlind(PIX, 0, PIX[1][1], 80, color)
tcas_main(TCAS_BUF, PIX, ts, te, dx, dy, 3)
# MAIN 存在方式 part2 (continued)
if te < te_ret:
tcas_main(TCAS_BUF, PIX_0, te, te_ret, dx, dy, 0)
ts2 = max(te, te_ret)
te2 = T2
tcas_main(TCAS_BUF, PIX_1, ts2, te2, dx, dy, 0)
# OUT 出场方式
ts3 = te2
te3 = T3
tcas_keyframe(TCAS_BUF, PIX_1, PixColorMul(PIX_1, 1, 1, 1, 0), ts3, te3, dx, dy, 1, 0)
num = len(PIX_list)
for i in range(num):
ts3 = te2 - 5 * _FD + i * _FD
te3 = ts3 + _FD
PIX = PIX_list[i]
if i > num - 5:
PIX = PixColorMul(PIX, 1, 1, 1, (num - i) / 5)
tcas_main(TCAS_BUF, PIX, ts3, te3, _x - PIX[1][0] / 2, _y - PIX[1][1] / 2, 2)
##### 将结果返回给tcax进行处理 #####
return (ASS_BUF, TCAS_BUF)
# 辅助函数
def Spectrum(fft, BANDS, SPECHEIGHT): # convert fft data to graph
bars = []
b0 = 0
for x in range(BANDS):
peak = 0 # peak of a certain bar
b1 = pow(2, x * 10 / (BANDS - 1))
if b1 > 1023:
b1 = 1023
if b1 <= b0:
b1 = b0 + 1 # make sure it uses at least 1 FFT bin
while b0 < b1:
if peak < fft[1 + b0]:
peak = fft[1 + b0]
b0 += 1
y = sqrt(peak) * 3 * SPECHEIGHT - 4 # 调整范围 sqrt使小值更加明显
if y > SPECHEIGHT:
y = SPECHEIGHT # 裁剪
bars.append(y)
return bars
def LinearLines(p, q, r, s, t, u, x):
if x < r:
return (x - p) * (s - q) / (r - p) + q
else:
return (x - r) * (u - s) / (t - r) + s
def Factor(x):
if x < 0.5:
return pow(2 * x, 0.3)
else:
return pow(2 * (1 - x), 0.3)
def SeedFill(TCAS_BUF, PIX, ts, te, dx, dy):
PIX_ori = PIX
width = PIX[1][0]
height = PIX[1][1]
points = PixPoints(PIX)
# make the boundary
boundary = []
for h in range(height):
boundary.append([])
for w in range(width):
boundary[h].append(-1) # -1 indicates the boundary
num = len(points) # number of points
for i in range(num):
w = points[i][0]
h = points[i][1]
boundary[h][w] = i # non-boundary area
dx0 = (0, 1, 0, -1)
dy0 = (1, 0, -1, 0)
# make the index
index = []
for i in range(num):
index.append(-1)
# rearrange the index
from collections import deque
left = num
while left > 0:
q = deque()
for i in range(num):
if index[i] == -1:
q.append(i)
index[i] = 0
break
while (len(q) > 0):
left -= 1
s = q.popleft()
pt = points[s]
for i in range(4):
x1 = pt[0] + dx0[i]
y1 = pt[1] + dy0[i]
if x1 >= 0 and x1 < width and y1 >= 0 and y1 < height and boundary[y1][x1] >= 0:
t = boundary[y1][x1]
if index[t] < 0:
index[t] = index[s] + 1
q.append(t)
# use index to create effects
indsc = 0.5
tp0_start = 10 * (ts + num / indsc + 2)
tp0_end = 0
tp0 = []
for i in range(num):
t = ts + 10 * (index[i] / indsc + 10 * RandGauss(-0.2, 0.2))
tp0.append(t)
tp0_start = min(tp0_start, t) # what we are doing is to create a series of PIXs to conver all the possible durations
tp0_end = max(tp0_end, t)
tp0_end += 7 * _FD
dur = tp0_end - tp0_start
frames = int(dur / _FD + 0.5)
for i in range(frames): # first of all, you should know how many frames we are going to make, then with each frame, what PIX we are going to use
PIX_li = [] # we need one PIX for each frame
PIX_li.append(PIX_ori[0])
PIX_li.append(PIX_ori[1])
temp = list(PIX_ori[2])
for j in range(num): # make the PIX
pt = points[j]
off = (pt[1] * width + pt[0]) * 4
if tp0_start + i * _FD < tp0[j]: # should be transparent
temp[off + 3] = 0
elif tp0_start + i * _FD < tp0[j] + 7 * _FD:
temp[off + 3] *= (tp0_start + i * _FD - tp0[j] + _FD) / (8 * _FD)
PIX_li.append(tuple(temp))
PIX = tuple(PIX_li)
tcas_main(TCAS_BUF, PIX, tp0_start + i * _FD, tp0_start + (i + 1) * _FD, dx, dy, 1)
tp0_end = tp0_start + frames * _FD
if tp0_end < te:
tcas_main(TCAS_BUF, PIX, tp0_end, te, dx, dy, 1)
return te
else:
return tp0_end
复制代码
附件:
Gundam_Seed_OP3.rar
(2012-7-20 07:37:19, 5.91 MB) / 下载次数 4150
http://tcax.org/forum.php?mod=attachment&aid=NjcxfDhjOTA1ZmI4fDE3MzIzMTI3NDZ8MHww
作者:
milkyjing
时间:
2012-7-20 07:40:28
预览待补。。。
http://player.youku.com/player.php/sid/XNDI5ODI0ODg4/v.swf
感谢木木上传
作者:
youkaze
时间:
2012-7-20 08:26:39
顶个 算是干掉一个坑了吧
作者:
mzlmcx
时间:
2012-7-20 19:57:03
话说怎么贴视频来着的= =
预览:
http://v.youku.com/v_show/id_XNDI5ODI0ODg4.html
作者:
milkyjing
时间:
2012-7-20 20:31:34
mzlmcx 发表于 2012-7-20 19:57
话说怎么贴视频来着的= =
预览:
http://v.youku.com/v_show/id_XNDI5ODI0ODg4.html
高级模式中,只有有Flash代码,点那个图标,粘帖入Flash地址就可以了。。
作者:
ひまり
时间:
2012-7-20 20:49:21
顶。。。
作者:
渣渣疯子
时间:
2012-7-23 21:36:52
支持一下
作者:
兜兜里没糖
时间:
2012-7-24 13:33:07
支持
作者:
milkyjing
时间:
2012-8-5 17:14:55
不能正确执行该工程的会员,请安装工程文件夹中的字体到系统。
仍然不行的会员,请用 abspath('op.mp3') 替换 'op.mp3'
ImagePix(abspath(img_path), img_size, 0) 替换 ImagePix(img_path, img_size, 0)
作者:
靠不住
时间:
2012-11-14 00:04:31
好好学习,天天向上
作者:
morofish
时间:
2013-8-6 22:17:37
改過還是不能執行啊,到底哪裡出錯了
欢迎光临 TCAX 字幕特效制作工具官方论坛 | ASS | TCAS | Python | Aegisub | Lua (http://tcax.org/)
Powered by Discuz! X2