TCAX 字幕特效制作工具官方论坛 | ASS | TCAS | Python | Aegisub | Lua

 找回密码
 新人加入
查看: 5046|回复: 10

[完整特效] [J]037_Gundam_Seed_OP3特效脚本 (附完整工程) [复制链接]

Administrator

TCAX Dev.

Rank: 7Rank: 7Rank: 7

发表于 2012-7-20 07:35:47 |显示全部楼层
说明:需要升级至少TCAX 1.1.9 SP1并添加tcAudio模块才可以正常执行本工程。
Gundam_Seed_OP3.rar (5.91 MB, 下载次数: 3209)
  1. from tcaxPy import *
  2. from util.gdiFont import *
  3. from util.tcAudio import *
  4. from util.magick import *
  5. from pixLibs.ImageStone import *

  6. def tcaxPy_Init():
  7.     global _Fs
  8.     global _FD          # 一帧的持续时间, 约40毫秒
  9.     global Font         # 首要字体
  10.     global FontOut      # 字体边框
  11.     global FontOut2     # 字体边框2
  12.     global FontShad      # 加粗字体
  13.     global GdiFontThin
  14.     _Fs = GetVal(val_FontSize)
  15.     _FD = 1000 / GetVal(val_FXFPS)
  16.     _FontFileName = GetVal(val_FontFileName)
  17.     _FaceID = GetVal(val_FaceID)
  18.     Font = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 0, False)
  19.     FontOut = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 4, True)
  20.     FontOut2 = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 2, True)
  21.     FontShad = InitFont(_FontFileName, _FaceID, _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), MakeRGB(0, 0, 0), 4, False)
  22.     GdiFontThin = gfInitFont(GetVal(val_FontFaceName), _Fs, GetVal(val_Spacing), GetVal(val_SpaceScale), -2.5, False)
  23.     # 初始化tcAudio, 本例是一个典型的tcAudio模块用法
  24.     global channel
  25.     tcAudioInit()
  26.     channel = tcAudioOpen('op.mp3')
  27.     # 颜色表
  28.     global color_op
  29.     color_op = ((1, 0, 0), # red
  30.                 (1, 1, 0), # yellow
  31.                 (1, 0, 1), # pink
  32.                 (0, 1, 0), # green
  33.                 (0, 1, 1), # sky blue
  34.                 (0, 1, 0), # green
  35.                 (1, 1, 0), # yellow
  36.                 (0, 1, 0), # green
  37.                 (0, 0, 1), # blue
  38.                 (1, 0, 1), # pink
  39.                 (1, 0, 0)) # red
  40.     # 各种K值
  41.     global minK
  42.     global meanK
  43.     global maxK
  44.     kar = GetVal(val_KarTime)
  45.     lineNum = GetVal(val_nLines)
  46.     textNum = GetVal(val_nTexts)
  47.     minK = 2 * 60 * 100
  48.     maxK = 0
  49.     SumK = 0
  50.     for i in range(lineNum):
  51.         SumLineK = 0
  52.         for j in range(textNum[i]):
  53.             SumLineK += kar[i][j]
  54.             minK = min(minK, kar[i][j])
  55.             maxK = max(maxK, kar[i][j])
  56.         SumK += SumLineK / textNum[i]
  57.     meanK = SumK / lineNum
  58.     # 图片序列
  59.     global PIX_list
  60.     PIX_list = []
  61.     num = 30
  62.     for i in range(1, num, 2):
  63.         img_path = MakePath(5, i, 'images', 'list', 'img', '.png', 'sys')
  64.         img_size = 5 * _Fs - 20
  65.         PIX = ImagePix(img_path, img_size, 0)
  66.         PIX_list.append(PIX)

  67. def tcaxPy_Fin():
  68.     FinFont(Font)
  69.     FinFont(FontOut)
  70.     FinFont(FontOut2)
  71.     FinFont(FontShad)
  72.     gfFinFont(GdiFontThin)
  73.     tcAudioFin()

  74. def tcaxPy_Main(_i, _j, _n, _start, _end, _elapk, _k, _x, _y, _a, _txt):
  75.     ASS_BUF  = []        # 保存ASS特效
  76.     TCAS_BUF = []        # 保存TCAS特效
  77.     ##### 主要特效编写操作 ####
  78.     dx = _x - int((_a + GetVal(val_Spacing)) / 2 + 0.5)     # 一个固定操作, 将an5的坐标转换为an7
  79.     dy = _y - int(_Fs / 2 + 0.5)    # ASS特效默认采用an5坐标, TCAS特效则采用an7坐标
  80.     # 文字主体
  81.     PIX = TextPix(Font, _txt)
  82.     PIX_t0 = PixColorRGB(PIX, DecRGB('FFFFFF'))     # 未增加内部填充
  83.     PIX = PixFromPoints(gfGetPoints(GdiFontThin, _txt))
  84.     PIX = PixColorRGB(PIX, DecRGB('111111'))
  85.     PIX_thin = PixBlur(PIX, 2)      # 内部填充
  86.     PIX_t = CombinePixs(PIX_t0, PIX_thin)    # 增加了内部填充的主体
  87.     # 边框主体
  88.     PIX = TextPix(FontOut, _txt)
  89.     PIX = PixColorRGB(PIX, DecRGB('000040'))
  90.     PIX_o = PixBlur(PIX, 6)
  91.     # 边框
  92.     PIX = TextPix(FontOut2, _txt)
  93.     PIX = PixColorRGB(PIX, DecRGB('AAAAAA'))
  94.     PIX_b = PixBlur(PIX, 4)
  95.     # 底色
  96.     PIX = TextPix(FontShad, _txt)
  97.     PIX = PixColorRGB(PIX, DecRGB('800080'))
  98.     PIX_s = PixBlur(PIX, 18)
  99.     # 混合
  100.     PIX = CombinePixs(PIX_s, PIX_o)
  101.     PIX = CombinePixs(PIX, PIX_b)
  102.     PIX_0 = CombinePixs(PIX, PIX_t0)
  103.     PIX_1 = CombinePixs(PIX, PIX_t)
  104.     # 一些时间的计算
  105.     T0 = 10 * _start - 12 * _FD + 1 * _j * _FD
  106.     T1 = T0 + 4 * _FD
  107.     T2 = 10 * _end + 5 * _FD - 2 * (_n - _j - 1) * _FD
  108.     T3 = T2 + 8 * _FD
  109.     # IN 入场方式 part1
  110.     img0 = pmgToImage(PIX_0)
  111.     num = 6
  112.     for i in range(num):
  113.         img = Image(img0)
  114.         img.motionBlur(0, (num - i) * 10, 0)
  115.         PIX = PixPos(pmgToPix(img), PIX_0[0][0], PIX_0[0][1])
  116.         ts0 = T0 + i * _FD
  117.         te0 = ts0 + _FD
  118.         tcas_main(TCAS_BUF, PIX, ts0, te0, dx, dy, 0)
  119.     # MAIN 存在方式 part1
  120.     ts1 = te0
  121.     te1 = 10 * (_start + _elapk)
  122.     tcas_main(TCAS_BUF, PIX_0, ts1, te1, dx, dy, 0)
  123.     # IN 入场方式 part2 种子填充算法应用
  124.     te_ret = SeedFill(TCAS_BUF, PIX_thin, T1, te1, dx, dy)
  125.     # EFT 表现方式
  126.     num = int(10 * _k / _FD + 0.5)
  127.     for i in range(num):
  128.         ts = te1 + _FD * i
  129.         te = ts + _FD
  130.         tcAudioSetPos(channel, tcAudioSec2Bytes(channel, ts / 1000))    # 设置音频文件指针位置为当前歌词
  131.         fft = tcAudioGetFFT(channel, 2048)  # 获取音频FFT数据, 取样数为2048
  132.         bars = Spectrum(fft, _n, 50)
  133.         bar_pct = max(bars[0:len(bars)//2]) / 50
  134.         factor = 1 + LinearLines(minK, 0.15, meanK, 0.4, maxK, 0.5, _k) * Factor(i / num)
  135.         PIX = PixResizeF(PIX_1, PIX_1[1][0] * factor, 0)
  136.         PIX = BilinearFilter(PIX, dx, dy)
  137.         color = MakeRGB(bar_pct * 255 * color_op[_i][0], bar_pct * 255 * color_op[_i][1], bar_pct * 255 * color_op[_i][2])
  138.         if random() < 1 / 3:
  139.             color = MakeRGB(bar_pct * 255, bar_pct * 255, bar_pct * 255)
  140.         PIX = pstBlind(PIX, 0, PIX[1][1], 80, color)
  141.         tcas_main(TCAS_BUF, PIX, ts, te, dx, dy, 3)
  142.     # MAIN 存在方式 part2 (continued)
  143.     if te < te_ret:
  144.         tcas_main(TCAS_BUF, PIX_0, te, te_ret, dx, dy, 0)
  145.     ts2 = max(te, te_ret)
  146.     te2 = T2
  147.     tcas_main(TCAS_BUF, PIX_1, ts2, te2, dx, dy, 0)
  148.     # OUT 出场方式
  149.     ts3 = te2
  150.     te3 = T3
  151.     tcas_keyframe(TCAS_BUF, PIX_1, PixColorMul(PIX_1, 1, 1, 1, 0), ts3, te3, dx, dy, 1, 0)
  152.     num = len(PIX_list)
  153.     for i in range(num):
  154.         ts3 = te2 - 5 * _FD + i * _FD
  155.         te3 = ts3 + _FD
  156.         PIX = PIX_list[i]
  157.         if i > num - 5:
  158.             PIX = PixColorMul(PIX, 1, 1, 1, (num - i) / 5)
  159.         tcas_main(TCAS_BUF, PIX, ts3, te3, _x - PIX[1][0] / 2, _y - PIX[1][1] / 2, 2)
  160.     ##### 将结果返回给tcax进行处理 #####
  161.     return (ASS_BUF, TCAS_BUF)


  162. # 辅助函数
  163. def Spectrum(fft, BANDS, SPECHEIGHT):      # convert fft data to graph
  164.     bars = []
  165.     b0 = 0
  166.     for x in range(BANDS):
  167.         peak = 0        # peak of a certain bar
  168.         b1 = pow(2, x * 10 / (BANDS - 1))
  169.         if b1 > 1023:
  170.             b1 = 1023
  171.         if b1 <= b0:
  172.             b1 = b0 + 1    # make sure it uses at least 1 FFT bin
  173.         while b0 < b1:
  174.             if peak < fft[1 + b0]:
  175.                 peak = fft[1 + b0]
  176.             b0 += 1
  177.         y = sqrt(peak) * 3 * SPECHEIGHT - 4    # 调整范围 sqrt使小值更加明显
  178.         if y > SPECHEIGHT:
  179.             y = SPECHEIGHT    # 裁剪
  180.         bars.append(y)
  181.     return bars

  182. def LinearLines(p, q, r, s, t, u, x):
  183.     if x < r:
  184.         return (x - p) * (s - q) / (r - p) + q
  185.     else:
  186.         return (x - r) * (u - s) / (t - r) + s

  187. def Factor(x):
  188.     if x < 0.5:
  189.         return pow(2 * x, 0.3)
  190.     else:
  191.         return pow(2 * (1 - x), 0.3)

  192. def SeedFill(TCAS_BUF, PIX, ts, te, dx, dy):
  193.     PIX_ori = PIX
  194.     width = PIX[1][0]
  195.     height = PIX[1][1]
  196.     points = PixPoints(PIX)
  197.     # make the boundary
  198.     boundary = []
  199.     for h in range(height):
  200.         boundary.append([])
  201.         for w in range(width):
  202.             boundary[h].append(-1)    # -1 indicates the boundary
  203.     num = len(points)    # number of points
  204.     for i in range(num):
  205.         w = points[i][0]
  206.         h = points[i][1]
  207.         boundary[h][w] = i    # non-boundary area
  208.     dx0 = (0, 1, 0, -1)
  209.     dy0 = (1, 0, -1, 0)
  210.     # make the index
  211.     index = []
  212.     for i in range(num):
  213.         index.append(-1)
  214.     # rearrange the index
  215.     from collections import deque
  216.     left = num
  217.     while left > 0:
  218.         q = deque()
  219.         for i in range(num):
  220.             if index[i] == -1:
  221.                 q.append(i)
  222.                 index[i] = 0
  223.                 break
  224.         while (len(q) > 0):
  225.             left -= 1
  226.             s = q.popleft()
  227.             pt = points[s]
  228.             for i in range(4):
  229.                x1 = pt[0] + dx0[i]
  230.                y1 = pt[1] + dy0[i]
  231.                if x1 >= 0 and x1 < width and y1 >= 0 and y1 < height and boundary[y1][x1] >= 0:
  232.                    t = boundary[y1][x1]
  233.                    if index[t] < 0:
  234.                        index[t] = index[s] + 1
  235.                        q.append(t)
  236.     # use index to create effects
  237.     indsc = 0.5
  238.     tp0_start = 10 * (ts + num / indsc + 2)
  239.     tp0_end = 0
  240.     tp0 = []
  241.     for i in range(num):
  242.         t = ts + 10 * (index[i] / indsc + 10 * RandGauss(-0.2, 0.2))
  243.         tp0.append(t)
  244.         tp0_start = min(tp0_start, t)    # what we are doing is to create a series of PIXs to conver all the possible durations
  245.         tp0_end = max(tp0_end, t)
  246.     tp0_end += 7 * _FD
  247.     dur = tp0_end - tp0_start
  248.     frames = int(dur / _FD + 0.5)
  249.     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
  250.         PIX_li = []    # we need one PIX for each frame
  251.         PIX_li.append(PIX_ori[0])
  252.         PIX_li.append(PIX_ori[1])
  253.         temp = list(PIX_ori[2])
  254.         for j in range(num):    # make the PIX
  255.             pt = points[j]
  256.             off = (pt[1] * width + pt[0]) * 4
  257.             if tp0_start + i * _FD < tp0[j]:    # should be transparent
  258.                 temp[off + 3] = 0
  259.             elif tp0_start + i * _FD < tp0[j] + 7 * _FD:
  260.                 temp[off + 3] *= (tp0_start + i * _FD - tp0[j] + _FD) / (8 * _FD)
  261.         PIX_li.append(tuple(temp))
  262.         PIX = tuple(PIX_li)
  263.         tcas_main(TCAS_BUF, PIX, tp0_start + i * _FD, tp0_start + (i + 1) * _FD, dx, dy, 1)
  264.     tp0_end = tp0_start + frames * _FD
  265.     if tp0_end < te:
  266.         tcas_main(TCAS_BUF, PIX, tp0_end, te, dx, dy, 1)
  267.         return te
  268.     else:
  269.         return tp0_end
复制代码

回帖推荐

milkyjing 发表于9楼  查看完整内容

不能正确执行该工程的会员,请安装工程文件夹中的字体到系统。 仍然不行的会员,请用 abspath('op.mp3') 替换 'op.mp3' ImagePix(abspath(img_path), img_size, 0) 替换 ImagePix(img_path, img_size, 0)
1

查看全部评分

Administrator

TCAX Dev.

Rank: 7Rank: 7Rank: 7

发表于 2012-7-20 07:40:28 |显示全部楼层
预览待补。。。



感谢木木上传

Rank: 4

发表于 2012-7-20 08:26:39 |显示全部楼层
顶个 算是干掉一个坑了吧

正式会员

妖木

Rank: 4

发表于 2012-7-20 19:57:03 |显示全部楼层
话说怎么贴视频来着的= =

预览:http://v.youku.com/v_show/id_XNDI5ODI0ODg4.html

Administrator

TCAX Dev.

Rank: 7Rank: 7Rank: 7

发表于 2012-7-20 20:31:34 |显示全部楼层
mzlmcx 发表于 2012-7-20 19:57
话说怎么贴视频来着的= =

预览:http://v.youku.com/v_show/id_XNDI5ODI0ODg4.html


高级模式中,只有有Flash代码,点那个图标,粘帖入Flash地址就可以了。。

Rank: 5Rank: 5

发表于 2012-7-20 20:49:21 |显示全部楼层
顶。。。

Moderator

疯子

Rank: 5Rank: 5

发表于 2012-7-23 21:36:52 |显示全部楼层
支持一下

Rank: 4

发表于 2012-7-24 13:33:07 |显示全部楼层
支持

Administrator

TCAX Dev.

Rank: 7Rank: 7Rank: 7

发表于 2012-8-5 17:14:55 |显示全部楼层
不能正确执行该工程的会员,请安装工程文件夹中的字体到系统。
仍然不行的会员,请用  abspath('op.mp3') 替换 'op.mp3'
ImagePix(abspath(img_path), img_size, 0) 替换 ImagePix(img_path, img_size, 0)

Rank: 4

发表于 2012-11-14 00:04:31 |显示全部楼层
好好学习,天天向上
1

查看全部评分

Rank: 1

发表于 2013-8-6 22:17:37 |显示全部楼层
改過還是不能執行啊,到底哪裡出錯了
您需要登录后才可以回帖 登录 | 新人加入

GitHub|TCAX 主页

GMT+8, 2024-7-18 15:54

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部
RealH