python自动制作gif并添加文字
引言
1. 处理gif以及基本思路
#### 我找到的原始的gif如下图1所示:就可以将`为所欲为.gif`分割成1.jpg,2.jpg,...。当然你也可以直接使用python的PIL库来处理gif,使用如下的代码即可:
```python
from PIL import Image,ImageSequence
gif = Image.open("为所欲为.gif")
for i,frame in enumerate(ImageSequence.Iterator(gif),1):
frame.save("%d.jpg" % i)
或者你也可以使用之前介绍过的moviepy库(具体可以参考我之前的一篇博客),如果你对opencv比较熟悉的话,自然也可以使用opencv来处理。这里就不详细说了。
得到gif的帧序列图像之后,简单来说一下后面处理的思路。因为原来的gif有些帧是有文字的,我们要想添加自己的文字,就必须要把原来的文字去除掉,然后换成自己的。所以后面基本的思路就是:
- 找出那些有文字出现的帧,把文字去除;
- 原来的文字去除之后,替换成自己的合适的文字,形成新的帧图像;
- 将新的帧图像合成为新的gif(这里使用moviepy合成)。
2. 实现代码以及简要解析
具体实现代码如下: ```python # -*- coding:utf-8 -*- import matplotlib.pyplot as plt from PIL import Image,ImageDraw,ImageFont from scipy.misc import imread,imsave,imresize import numpy as np import os from glob import glob from moviepy.editor import ImageSequenceClip # 消除文字的图片序号 modify_img_index = list(range(11,14))+list(range(27,37)) + list(range(44,61)) + list(range(62,81)) \ + list(range(82,94)) + list(range(97,106)) + list(range(112,132)) + list(range(146,168)) text_info = [('好啊',(120,140))]*(14-11) + \ [('就算你今天找人来抗议',(40,140))]*(37-27) + \ [('就算你的理由再完美',(50,140))] *(61-44) + \ [('我想不退钱就不退钱',(50,140))] *(81-62) + \ [('毕竟我是东北黑中介',(50,140))] *(94-82) + \ [('东北黑中介了不起啊',(50,140))] *(106-97) + \ [('sorry,东北黑中介真的可以为所欲为',(5,140))]*(132-112) + \ [('以后让他天天闹',(60,140))]*(158-146) + \ [('天天闹',(110,140))]*(169-158) index_to_text = dict(zip(modify_img_index,text_info)) # 保存图片文件夹 save_dir = "output" if not os.path.exists(save_dir): os.mkdir(save_dir) new_color = np.array([50,50,50]) # 消除文字之后的颜色 fontsize = 18 fontcolor = (0,255,255) fps = 10 resize_scale = 1.5 # 新图的宽和高是原来的多少倍 # 消除文字的x,y边界坐标 y_begin = 10 y_end = 280 x_begin = 140 x_end = 160 # 全部文件列表(无序) img_names = glob("*.jpg") #print(img_names) def modify(): # 遍历每一个图像 for img_name in img_names: img = imread(img_name) h,w = img.shape[0],img.shape[1] #plt.imshow(img) img_new = np.copy(img) index = int(img_name.split(".")[0]) # 如果图片有文字,需要修改 if index in modify_img_index: # 消除文字 img_new[x_begin:x_end,y_begin:y_end] = new_color text,pos = index_to_text[index] img_new = drawtext(Image.fromarray(img_new),text,pos,fontsize,fontcolor) #保存新的图片 # imsave(os.path.join(save_dir,img_name),img_new) if resize_scale != 1: # resize img_new = img_new.resize((int(w*resize_scale),int(h*resize_scale))) img_new.save(os.path.join(save_dir,img_name)) print("Modify and save %s!" % img_name) else: # 没有文字,不需要修改,直接保存原来的图片 if resize_scale != 1: img = imresize(img,resize_scale) imsave(os.path.join(save_dir,img_name),img) print("Save %s!" % img_name) def drawtext(img,text,pos,fontsize,fontcolor): ''' draw text for img @param img:image to draw text @param text:text to draw @param pos:where to draw the text((x,y)) @param fontsize: font size @param fontcolor: font color ''' font = ImageFont.truetype("simsun.ttc",fontsize) draw = ImageDraw.Draw(img) draw.text(pos,text,fontcolor,font = font) # plt.imshow(img) # plt.show() return img def test_drawtext(): img_name = "4.jpg" img = Image.open(img_name) #text = "好啊" text = "东北黑中介了不起啊" pos = (40,140) fontsize = 20 fontcolor = (0,255,255) drawtext(img,text,pos,fontsize,fontcolor) # 利用图像序列生成gif def generate_gif(img_names,save_path,fps = 10): # img_names:list of image names clip = ImageSequenceClip(img_names,fps = fps) clip.write_gif(save_path) print("Write %s successfully!" % save_path)主函数
def main():
modify()
save_gif_path = os.path.join(save_dir,"东北黑中介.gif")
img_names = sorted(glob(os.path.join(save_dir,"*.jpg")),key = lambda x: int(x.split(".")[0].split("/")[1]))
generate_gif(img_names,save_gif_path,fps)
test_drawtext()
if name == 'main':
main()
上面的代码思路其实还是比较清楚的。主要麻烦的地方就在于,我们没法自动确认哪些帧出现了文字,所以在这里我采用手动观察图像(有167张图)的方式,确定了出现文字的帧序列区间;然后对于这些帧序列区间,其文字替换成我自己的文字。还有一个问题就是,我要消除文字,就要知道文字的位置,其实这个可以归结为一个目标检测的问题,或者说是一个OCR问题(OCR的第一步,定位文字),但是OCR做起来还是很麻烦的,这里暂时不说,后面有空我会专门讨论OCR问题。这里比较好的地方在于,所有的文字出现的高度位置几乎是一样的,只是宽度方向的位置不一样(有的字多,有的字少),这里我还是采用手动观察标注的办法,可以借助于matplotlib显示图像,用鼠标点击图像的某一点,它会显示该点的(x,y)坐标和像素值,这样我们就可以手动确定要消除的文字的位置,以及消除文字要填充的颜色了。按照这个思路,我们可以得到一些消除原来文字,添加新文字之后的图像如下图2所示:
<center><div><img src="http://t1.aixinxi.net/o_1cem488ad1tkk3pe16pb7jn10lva.jpg-w.jpg"></div></center>
<center>图2 原始帧和消除文字后添加新文字的帧(上是原始帧,下是处理之后的新帧)</center>
最终合成的新的gif如下图3所示:
<center><div><img src="http://t1.aixinxi.net/o_1cem4hohk1nkc1r7f1rkt37h1pu3a.gif-w.jpg"></div></center>
<center>图3 最终合成的gif</center>
<h2>3. 小结</h2>
#### 本文主要利用python的PIL库(用于处理图像,添加文字等)和moviepy(用于生成gif)自动生成了gif并添加了文字。但是还有一些问题,比如文字自动定位并识别没有解决。这些问题留到后面介绍OCR技术的时候再和大家介绍。如果只是简单地尝试合成gif,大家不妨自己动手试一试。
<center><h1>全文完,感谢阅读!</h1></center>
热爱编程,热爱机器学习!
github:http://www.github.com/Lyrichu
github blog:http://Lyrichu.github.io
个人博客站点:http://www.movieb2b.com(不再维护)