-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
example_direct.py
executable file
·155 lines (123 loc) · 4.58 KB
/
example_direct.py
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
import os
import shutil
import numpy as np
from apngasm_python._apngasm_python import (APNGAsm, APNGFrame,
create_frame_from_rgb,
create_frame_from_rgb_trns,
create_frame_from_rgba)
from PIL import Image
file_dir = os.path.split(__file__)[0]
samples_dir = os.path.join(file_dir, "../samples")
frames_dir = os.path.join(samples_dir, "frames")
input_dir = os.path.join(samples_dir, "input")
output_dir = os.path.join(samples_dir, "output")
ball_apng_path = os.path.join(input_dir, "ball.apng")
grey_png_path = os.path.join(input_dir, "grey.png")
palette_png_path = os.path.join(input_dir, "palette.png")
def frame_info(frame: APNGFrame):
print(f"{frame.pixels = }")
print(f"{frame.width = }")
print(f"{frame.height = }")
print(f"{frame.color_type = }")
print(f"{frame.palette = }")
print(f"{frame.transparency = }")
print(f"{frame.palette_size = }")
print(f"{frame.transparency_size = }")
print(f"{frame.delay_num = }")
print(f"{frame.delay_den = }")
# https://www.w3.org/TR/PNG-Chunks.html
color_type_dict = {0: "L", 2: "RGB", 3: "P", 4: "LA", 6: "RGBA"}
color_type_dict.update(dict((v, k) for k, v in color_type_dict.items())) # type: ignore
# Cleanup
shutil.rmtree(output_dir, ignore_errors=True)
os.mkdir(output_dir)
# Initialize
apngasm = APNGAsm()
# Get libapngasm version
print(f"{apngasm.version() = }")
# Load png from one directory
for file_name in sorted(os.listdir(frames_dir)):
apngasm.add_frame_from_file(os.path.join(frames_dir, file_name), 100, 1000)
# Getting information about one frame
frame = apngasm.get_frames()[0]
frame_info(frame)
# Saving one frame as file
out = os.path.join(output_dir, "elephant-frame.png")
frame.save(out)
# Getting one frame as Pillow Image
mode = color_type_dict[frame.color_type]
im = Image.frombytes(mode, (frame.width, frame.height), frame.pixels) # type: ignore
out = os.path.join(output_dir, "elephant-frame-pillow.png")
im.save(out)
# Get inforamtion about whole animation
print(f"{apngasm.get_loops() = }")
print(f"{apngasm.is_skip_first() = }")
print(f"{apngasm.frame_count() = }")
# Assemble
out = os.path.join(output_dir, "elephant.png")
success = apngasm.assemble(out)
print(f"{success = }")
# Clear images loaded in apngasm object
apngasm.reset()
# Disassemble and get pillow image of one frame
frames = apngasm.disassemble(ball_apng_path)
print(f"{len(frames) = }")
frame = frames[0]
frame_info(frame)
mode = color_type_dict[frame.color_type]
im = Image.frombytes(mode, (frame.width, frame.height), frame.pixels) # type: ignore
out = os.path.join(output_dir, "ball0.png")
im.save(out)
# Disassemble all APNG into PNGs
apngasm.save_pngs(output_dir)
# Assemble from pillow images
# Just for fun, let's also make it spin
apngasm.reset()
angle = 0.0
angle_step = 360 / len(os.listdir(frames_dir))
for file_name in sorted(os.listdir(frames_dir)):
image = Image.open(os.path.join(frames_dir, file_name))
image = image.rotate(angle)
frame = create_frame_from_rgba(np.array(image), image.width, image.height)
apngasm.add_frame(frame)
angle += angle_step
out = os.path.join(output_dir, "elephant-spinning-pillow.apng")
success = apngasm.assemble(out)
print(f"{success = }")
# Assemble palette and grey PNGs
apngasm.reset()
apngasm.add_frame_from_file(palette_png_path, 100, 1000)
apngasm.add_frame_from_file(grey_png_path, 100, 1000)
frame0 = apngasm.get_frames()[0]
frame_info(frame0)
frame1 = apngasm.get_frames()[1]
frame_info(frame1)
out = os.path.join(output_dir, "birds.apng")
success = apngasm.assemble(out)
print(f"{success = }")
del apngasm
# Assemble palette and grey PNGs, but with Pillow
image0 = Image.open(grey_png_path).convert("RGB")
frame0 = create_frame_from_rgb(np.array(image0), image0.width, image0.height, 1, 1)
frame_info(frame0)
image1 = Image.open(grey_png_path).convert("RGB")
frame1 = create_frame_from_rgb_trns(
np.array(image1), image0.width, image0.height, np.array([255, 255, 255]), 1, 1
)
frame_info(frame1)
# You may even set the variables manually
image2 = Image.open(palette_png_path).convert("RGBA")
frame2 = APNGFrame()
frame2.delay_num = 1
frame2.delay_den = 1
frame2.color_type = color_type_dict[image2.mode] # type: ignore
frame2.width = image2.width
frame2.height = image2.height
frame2.pixels = np.array(image2)
frame_info(frame2)
# Another way of creating APNGAsm object
apngasm = APNGAsm([frame0, frame1, frame2]) # type: ignore
out = os.path.join(output_dir, "birds-pillow.apng")
success = apngasm.assemble(out)
print(f"{success = }")