-
Notifications
You must be signed in to change notification settings - Fork 0
/
captiongif.py
executable file
·135 lines (95 loc) · 3.74 KB
/
captiongif.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
#!/usr/bin/env python
from PIL import Image, ImageDraw, ImageSequence, ImageFont, GifImagePlugin
import textwrap
import io
import sys
import argparse
import re
from pathlib import Path
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
parser = argparse.ArgumentParser(prog='Gif Captioner', description='Captions your gifs like the funny iFunny gifs')
parser.add_argument('-i', '--input')
parser.add_argument('string')
args = vars(parser.parse_args())
message = args["string"]
inputFile = args["input"]
# inputFile = sys.argv[1]
if inputFile.endswith('.gif'):
originalGif = Image.open(inputFile)
else:
print("Input file is not a gif!")
exit(1)
fontName = "futura_black.otf"
# font size of 32
font = ImageFont.truetype(fontName, 32)
def resize_gif(gif, Width):
frames = []
for frame in ImageSequence.Iterator(gif):
new_gif = frame.copy()
widthPercent = (Width / float(new_gif.size[0]))
hsize = int((float(new_gif.size[1]) * float(widthPercent)))
new_gif = new_gif.resize((Width, hsize), Image.Resampling.LANCZOS)
new_gif.info = frame.info
frames.insert(0, new_gif)
frames[0].info = originalGif.info
fobj = io.BytesIO()
frames[0].save(fobj, 'GIF', save_all=True, append_images=frames[1:], optimize=False, disposal=2)
return Image.open(fobj)
lineWrapMax = 24
# if the gif is too small we scale it up and change the font size and linewrap max
if originalGif.height < 360:
#baseWidth = 360
#print("baby size")
font = ImageFont.truetype(fontName, 28)
originalGif = resize_gif(originalGif, 360)
# weird ratio edge case, change font size and change linewrap
ratio = originalGif.height / originalGif.width
if ratio >= 1.0 :
#print("weird ratio")
font = ImageFont.truetype(fontName, 28)
lineWrapMax = 20
# more weird ratio edge cases
if ratio <= 1.8 and ratio >= 1.4:
# print("tall ratio")
font = ImageFont.truetype(fontName, 28)
lineWrapMax = 14
messageSplit = message.split(' ')
messageWrap = textwrap.wrap(message, width=lineWrapMax)
messageFill = textwrap.fill(message, width=lineWrapMax)
# big text if short message
if len(messageWrap) == 1 and (len(message) < 14):
#print("weird ratio")
font = ImageFont.truetype(fontName, 48)
# frames = ImageSequence.Iterator(originalGif)
newGif = originalGif.copy()
newGif.thumbnail((480, 360)) # just to get new size properly
captionText = Image.new(mode="RGBA", size=(newGif.width, newGif.height + 1000), color="white")
draw = ImageDraw.Draw(captionText)
W = newGif.width
H = newGif.height + 1000
_, _, _, line_height = font.getbbox(message)
current_h = line_height
lineCount = 0
for line in messageWrap:
_, _, w, h = draw.textbbox((0, 0), line, font=font)
draw.text(((W - w) / 2, current_h), line, font=font, fill="black")
current_h += line_height
lineCount += 1
# crop to make make message fit nice
_, cropTop, _, cropBottom = font.getbbox(messageFill)
captionText = captionText.crop((0, 0, W, lineCount * line_height + line_height + line_height))
# captionText = captionText.resize((originalGif.width, originalGif.height))
frames = []
for frame in ImageSequence.Iterator(originalGif):
frame = frame.copy()
frame.thumbnail((480, 360))
new_frame = Image.new('RGBA', (newGif.width, newGif.height + captionText.height), (0, 0, 0, 0))
new_frame.paste(captionText, (0, 0))
new_frame.paste(frame, (0, captionText.height))
new_frame.info = frame.info
frames.insert(0, new_frame)
frames[0].info = originalGif.info
# making the cool filename
outputFilename = "_".join(messageSplit[:6]) + "_[" + Path(inputFile).stem + "gif]_" + ".gif"
# saving final gif
frames[0].save(outputFilename, save_all=True, append_images=frames[1:], disposal=2)