File size: 2,388 Bytes
e629302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import numpy as np
import cv2
import numexpr
from PIL import Image

def parse_keyframe_string(string, max_frames):
    res = np.ones(max_frames)
    parts = string.split(",")
    keyframes = {}
    for part in parts:
        try:
            k, v = part.split(":")
            keyframes[int(k.strip())] = v.strip("() ")
        except: continue
    
    sorted_keys = sorted(keyframes.keys())
    for i in range(len(sorted_keys)):
        start_f = sorted_keys[i]
        end_f = sorted_keys[i+1] if i+1 < len(sorted_keys) else max_frames
        val_str = keyframes[start_f]
        
        for f in range(start_f, end_f):
            if val_str.replace('.','',1).isdigit():
                res[f] = float(val_str)
            else:
                try:
                    res[f] = numexpr.evaluate(val_str, local_dict={'t': f, 'sin': np.sin, 'cos': np.cos, 'pi': np.pi}).item()
                except:
                    res[f] = res[f-1] if f > 0 else 0.0
    return res

def maintain_colors(prev_img, target_img):
    """Matches the color histogram of the new frame to the first frame/previous frame."""
    prev_img_cv = cv2.cvtColor(np.array(prev_img), cv2.COLOR_RGB2LAB)
    target_img_cv = cv2.cvtColor(np.array(target_img), cv2.COLOR_RGB2LAB)
    
    avg_l, avg_a, avg_b = np.mean(prev_img_cv[:,:,0]), np.mean(prev_img_cv[:,:,1]), np.mean(prev_img_cv[:,:,2])
    target_img_cv[:,:,0] = np.clip(target_img_cv[:,:,0] + (avg_l - np.mean(target_img_cv[:,:,0])), 0, 255)
    target_img_cv[:,:,1] = np.clip(target_img_cv[:,:,1] + (avg_a - np.mean(target_img_cv[:,:,1])), 0, 255)
    target_img_cv[:,:,2] = np.clip(target_img_cv[:,:,2] + (avg_b - np.mean(target_img_cv[:,:,2])), 0, 255)
    
    return Image.fromarray(cv2.cvtColor(target_img_cv, cv2.COLOR_LAB2RGB))

def anim_frame_warp(img, angle, zoom, translation_x, translation_y):
    width, height = img.size
    center = (width // 2, height // 2)
    matrix = cv2.getRotationMatrix2D(center, angle, zoom)
    matrix[0, 2] += translation_x
    matrix[1, 2] += translation_y
    return Image.fromarray(cv2.warpAffine(np.array(img), matrix, (width, height), borderMode=cv2.BORDER_REPLICATE))

def lerp_frames(frame1, frame2, alpha):
    arr1 = np.array(frame1).astype(np.float32)
    arr2 = np.array(frame2).astype(np.float32)
    blended = arr1 * (1 - alpha) + arr2 * alpha
    return Image.fromarray(blended.astype(np.uint8))