python自动制作gif并添加文字

简介: 引言    最近租的房子快到期了,哎,因为去年是第一次找房子租,结果遇到了一个东北黑中介,押一付三,房子有啥问题,灯坏了,下水道堵了,原来签合同的时候说的客气,说是马上就会上门解决,结果实际上我每次找他,都是各种推脱,最后不了了之。

引言

    最近租的房子快到期了,哎,因为去年是第一次找房子租,结果遇到了一个东北黑中介,押一付三,房子有啥问题,灯坏了,下水道堵了,原来签合同的时候说的客气,说是马上就会上门解决,结果实际上我每次找他,都是各种推脱,最后不了了之。全部是我自己想办法解决的。现在又打电话催着我要搬走,押金也不打算退给我了。真的是rlgl。我反对地域黑,但是以后东北的中介一生黑。(再次声明,不是地域黑,我也有认识的人很好的东北的朋友。)今天我又看到了有钱可以为所欲为的经典gif,所以我心血来潮想做一个自己的东北黑中介版的为所欲为gif。本来我想找一个没有文字的gif,然后找一个软件添加文字,然后合成gif的。结果在网上搜索了一下,没有找到合适的原版gif,只找到了一个有文字的gif。到是有软件可以手动添加文字合成gif的,但是如果要首先把原来的文字去除,然后再一点点添加,手动要做大量的工作,很是麻烦。我再尝试了半个小时还没弄好就放弃了(但是我想应该有比较简便的方法,只是我懒得再自己去找了)。最后我想既然作为一个程序员,能不能通过代码去实现这个功能呢?当然可以啦。我最熟悉的是python,自然优先考虑上python了。之前接触过PIL这个库,我记得它有给图片添加文字的功能,而且最近不是才刚刚看了moviepy这个库,它可以很容易合成gif,把这两个结合到一起不就很容易实现我想要的目标了吗?一不做二不休,开搞!

1. 处理gif以及基本思路

    我找到的原始的gif如下图1所示:

o_1cem1dj0ii4s16a22q12hn287a.gif-w.jpg
图1 原始"为所欲为"gif(来自微博)

如果你的电脑已经安装了ffmpeg的话,那么将gif分割成单帧的序列图片是非常容易的,运行下面的命令:

ffmpeg -i 为所欲为.gif %d.jpg

就可以将为所欲为.gif分割成1.jpg,2.jpg,...。当然你也可以直接使用python的PIL库来处理gif,使用如下的代码即可:

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. 实现代码以及简要解析

具体实现代码如下:

# -*- 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所示:

o_1cem488ad1tkk3pe16pb7jn10lva.jpg-w.jpg

图2 原始帧和消除文字后添加新文字的帧(上是原始帧,下是处理之后的新帧)
    最终合成的新的gif如下图3所示:
o_1cem4hohk1nkc1r7f1rkt37h1pu3a.gif-w.jp

图3 最终合成的gif

3. 小结

    本文主要利用python的PIL库(用于处理图像,添加文字等)和moviepy(用于生成gif)自动生成了gif并添加了文字。但是还有一些问题,比如文字自动定位并识别没有解决。这些问题留到后面介绍OCR技术的时候再和大家介绍。如果只是简单地尝试合成gif,大家不妨自己动手试一试。

全文完,感谢阅读!

热爱编程,热爱机器学习! github:http://www.github.com/Lyrichu github blog:http://Lyrichu.github.io 个人博客站点:http://www.movieb2b.com(不再维护)
目录
相关文章
|
2月前
|
数据挖掘 数据安全/隐私保护 开发者
使用Spire.PDF for Python插件从PDF文件提取文字和图片信息
使用Spire.PDF for Python插件从PDF文件提取文字和图片信息
123 0
|
6月前
|
编解码 Linux Python
Python:把视频转为Gif图片
Python:把视频转为Gif图片
71 0
|
7月前
|
人工智能 机器人 UED
AIGC革新,将文字或者LOGO融入AI视频基于PIKA-labs(Python3.10)
很多平台都会禁止用户使用带有网址或者二维码的头像以及文章配图,这样可以有效的防止用户的一些“导流”行为。当然,头像、文章或者视频现在都是AI来审,毕竟现在人工的成本实在太高,但是如果我们把文字元素直接融入图像或者视频之中,如此一来,AI也会很难识别出一些“导流”的元素。 本次我们依靠PIKA-labs平台,无需本地环境,直接简单粗暴输出带有文字元素的光影视频效果,基于Python3.10。
AIGC革新,将文字或者LOGO融入AI视频基于PIKA-labs(Python3.10)
|
8月前
|
Python Windows
用 Python 将神龙大侠搞怪 GIF 转为字符动画
用 Python 将神龙大侠搞怪 GIF 转为字符动画
60 0
用 Python 将神龙大侠搞怪 GIF 转为字符动画
|
7天前
|
存储 计算机视觉 Python
python实现Gif图片的字符画
这是一个Python实战项目,旨在将GIF动态图转化为ASCII字符动画。项目适合有一定Python基础的学习者,主要使用os、imageio、PIL库。首先,代码导入所需库,然后通过PIL创建空白图片并添加文本。接着,程序读取GIF,拆分帧并转为字符画,存入“tmp”目录。同时,代码提供了清空“tmp”目录、将灰度值映射为ASCII字符、将图片处理成字符画的函数。此外,还有创建新画布和合成GIF的步骤。主函数调用这些模块,最终将ASCII字符画合并成GIF。项目展示了将动态图像转换为ASCII艺术的过程。
|
2月前
|
文字识别 数据挖掘 网络安全
Python实现avif图片转jpg格式并识别图片中的文字
在做数据分析的时候有些数据是从图片上去获取的,这就需要去识别图片上的文字。Python有很多库可以很方便的实现OCR识别图片中的文字。这里介绍用EasyOCR库进行图片文字识别。easyocr是一个比较流行的库,支持超过80种语言,识别率高,速度也比较快。
32 2
|
2月前
|
图形学 计算机视觉 Python
Python如何利用PIL工具包制作gif动画效果
Python如何利用PIL工具包制作gif动画效果
42 0
|
2月前
|
机器学习/深度学习 文字识别 数据安全/隐私保护
Python实现从PDF和图片提取文字的方法总结
Python实现从PDF和图片提取文字的方法总结
68 0
|
2月前
|
人工智能 开发工具 git
第一次运行 Python 项目,使用 python-pptx 提取 ppt 中的文字和图片
人工智能时代,最需要学习的编程语言是:python 。笔者是个 python 小白,昨天花了两个小时,第一次成功运行起来 python 项目 。 项目是 powerpoint-extractor ,可以将 ppt 文件中的图片提取出来,并输出到固定的目录。
第一次运行 Python 项目,使用 python-pptx 提取 ppt 中的文字和图片
|
7月前
|
API Python
Python制作gif动图
Python制作gif动图。更多内容请关注本人微信公众号:python学习杂记