最近”Sorry 有钱真的能为所欲为”GIF突然爆红网络,那种贱贱的表情,可以给人暴击
于是产生念头,自己做一个Sorry GIF的字幕合成器,嘿嘿
由于时间仓促+智商有限,我仅仅做了一个简易的版本,高级版本可以行百度
思路分享
由于GIF是由一帧帧的GIF组成,我们可以把GIF的每一帧保存下来,然后在特定帧上插上文字,再把一系列的图合成GIF就可。
当然有几个细节需要注意,其一是插上的文字后,起始位置需要根据文字的长度调整,其二是文件名的灵活性
GIF分解为PNG
在这儿我们利用到了PIL图像处理库进行处理
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 |
#-*- coding: UTF-8 -*- import os from PIL import Image def analyseImage(path): ''''' Pre-process pass over the image to determine the mode (full or additive). Necessary as assessing single frames isn't reliable. Need to know the mode before processing all frames. ''' im = Image.open(path) results = { 'size': im.size, 'mode': 'full', } try: while True: if im.tile: tile = im.tile[0] update_region = tile[1] update_region_dimensions = update_region[2:] if update_region_dimensions != im.size: results['mode'] = 'partial' break im.seek(im.tell() + 1) except EOFError: pass return results def processImage(path): ''''' Iterate the GIF, extracting each frame. ''' mode = analyseImage(path)['mode'] im = Image.open(path) i = 0 p = im.getpalette() last_frame = im.convert('RGBA') try: while True: print ("saving %s frame %d, %s %s" % (path, i, im.size, im.tile)) ''''' If the GIF uses local colour tables, each frame will have its own palette. If not, we need to apply the global palette to the new frame. ''' if not im.getpalette(): im.putpalette(p) new_frame = Image.new('RGBA', im.size) ''''' Is this file a "partial"-mode GIF where frames update a region of a different size to the entire image? If so, we need to construct the new frame by pasting it on top of the preceding frames. ''' if mode == 'partial': new_frame.paste(last_frame) new_frame.paste(im, (0,0), im.convert('RGBA')) new_frame.save('%s-%d.jpg' % (''.join(os.path.basename(path).split('.')[:-1]), i), 'PNG') i += 1 last_frame = new_frame im.seek(im.tell() + 1) except EOFError: pass def main(): processImage('sorry_1.gif') if __name__ == "__main__": main() |
插上文字
这里需要输入字体文件,可从网上下载你喜欢的字体
1 2 3 4 5 6 7 |
from PIL import Image,ImageFont,ImageDraw im=Image.open('./base/sorry-10.png') draw=ImageDraw.Draw(im) newfont=ImageFont.truetype('heiti.TTF',20) draw.text((120,140),'好啊',(255,255,255),font=newfont) #文字起始位子、内容、颜色、字体 im.show() |
合成GIF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#-*- coding: UTF-8 -*- import imageio def main(): frames = [] for i in range(167): frames.append(imageio.imread("f-sorry_1-"+str(i)+".jpg")) #print("sorry-"+str(i)+".png") imageio.mimsave("out1.gif", frames, 'GIF', duration = 0.1) return if __name__ == "__main__": main() |
随便生成了个玩玩哈