-
Notifications
You must be signed in to change notification settings - Fork 0
/
writeGif.py
92 lines (78 loc) · 2.27 KB
/
writeGif.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
from io import BytesIO
import time
import driver
import time
import sys
from PIL import Image, ImageSequence
if len(sys.argv) < 3:
print("Usage: python ./writeGif.py /path/to/your/file.gif <rotation 0|90|180|270>")
sys.exit(1)
def sizeof_fmt(num, suffix="B"):
for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
if abs(num) < 1024.0:
return f"{num:3.1f}{unit}{suffix}"
num /= 1024.0
return f"{num:.1f}Yi{suffix}"
lcd = driver.KrakenLCD()
MIN_COLORS = 16
rotation = int(sys.argv[2])
gifData = None
found = False
iteration = 0
colorBoundary = [MIN_COLORS, 256]
iteration = 0
previousRun = (0, 0)
img = Image.open(sys.argv[1])
while not found:
colors = colorBoundary[0] + (colorBoundary[1] - colorBoundary[0]) // 2
byteio = BytesIO()
# Get sequence iterator
frames = ImageSequence.Iterator(img)
newFrames = []
for frame in frames:
frame = frame.convert("RGB").rotate(rotation)
pal = frame.quantize(colors)
newFrame = frame.quantize(
colors, palette=pal, dither=Image.FLOYDSTEINBERG
).resize(
lcd.resolution,
Image.Resampling.LANCZOS,
)
newFrames.append(newFrame)
om = newFrames[0]
om.info = img.info # Copy sequence info
om.save(
byteio,
"GIF",
interlace=False,
optimize=True,
save_all=True,
append_images=newFrames,
)
gifData = byteio.getvalue()
gifSize = len(gifData)
print(
"Iteration {:2}: {} colors size {}, {}".format(
iteration + 1, colors, sizeof_fmt(gifSize), colorBoundary
)
)
iteration = +1
if gifSize > lcd.maxBucketSize:
colorBoundary[1] = colors
else:
colorBoundary[0] = colors
# no size increase despite color increase, we can stop
if (previousRun[0] <= colors and previousRun[1] == gifSize) or (
colorBoundary[1] - colorBoundary[0] < 10
):
print("found")
found = True
previousRun = (colors, gifSize)
if iteration == 20:
sys.exit(1)
lcd.setLcdMode(driver.DISPLAY_MODE.LIQUID, 0x0)
time.sleep(0.1)
lcd.deleteAllBuckets()
lcd.createBucket(0, size=len(gifData))
lcd.writeGIF(gifData, 0, fast=False)
lcd.setLcdMode(0x4, 0x0)