python自動製作gif並新增文字
引言
最近租的房子快到期了,哎,因為去年是第一次找房子租,結果遇到了一個東北黑中介,押一付三,房子有啥問題,燈壞了,下水道堵了,原來籤合同的時候說的客氣,說是馬上就會上門解決,結果實際上我每次找他,都是各種推脫,最後不了了之。全部是我自己想辦法解決的。現在又打電話催著我要搬走,押金也不打算退給我了。真的是rlgl。我反對地域黑,但是以後東北的中介一生黑。(再次宣告,不是地域黑,我也有認識的人很好的東北的朋友。)今天我又看到了有錢可以為所欲為
的經典gif,所以我心血來潮想做一個自己的東北黑中介
版的為所欲為
gif。本來我想找一個沒有文字的gif,然後找一個軟體新增文字,然後合成gif的。結果在網上搜尋了一下,沒有找到合適的原版gif,只找到了一個有文字的gif。到是有軟體可以手動新增文字合成gif的,但是如果要首先把原來的文字去除,然後再一點點新增,手動要做大量的工作,很是麻煩。我再嘗試了半個小時還沒弄好就放棄了(但是我想應該有比較簡便的方法,只是我懶得再自己去找了)。最後我想既然作為一個程式設計師,能不能通過程式碼去實現這個功能呢?當然可以啦。我最熟悉的是python,自然優先考慮上python了。之前接觸過PIL這個庫,我記得它有給圖片新增文字的功能,而且最近不是才剛剛看了moviepy這個庫,它可以很容易合成gif,把這兩個結合到一起不就很容易實現我想要的目標了嗎?一不做二不休,開搞!
1. 處理gif以及基本思路
我找到的原始的gif如下圖1所示:
圖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所示:
圖2 原始幀和消除文字後新增新文字的幀(上是原始幀,下是處理之後的新幀)
最終合成的新的gif如下圖3所示:
圖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(不再維護)
相關文章
- GIF動圖怎麼製作?GIF圖片製作
- GIF動畫線上製作動畫
- 如何製作GIF表情包,動態GIF怎麼做
- GIF動態圖怎麼製作
- 如何製作有趣的GIF動態圖
- 攻略:如何製作動態的GIF圖
- 怎麼製作gif動態圖 QQ動態表情包怎麼製作
- 如何製作動態圖,GIF怎麼在電腦上製作
- 自己怎麼製作GIF表情包 QQ動態圖如何製作
- GIF動畫製作軟體哪個好動畫
- 製作GIF動態圖有什麼方法
- 怎麼製作GIF高清動態表情包
- 有什麼好用的gif製作軟體 製作GIF表情包教程
- 錄屏製作gif工具
- 抖音GIF表情包製作教程 如何製作QQ動態表情包
- 哪個軟體可以製作GIF表情包 動態圖製作方法
- html最簡單的Gif圖動畫製作方法gif轉base64HTML動畫
- fig動圖和影片製作器:Gif and Video Maker for MacIDEMac
- 遇見抖音沙漠駱駝gif表情包 如何製作自己的gif動態圖
- 動態新增或減少文字框,並獲取文字框值
- 製作GIF的軟體什麼好用
- PS製作抽象人物線條GIF動態圖片效果抽象
- 王境澤表情包出處,怎麼製作GIF動態圖?
- mac用什麼軟體製作GIF方便?Mac
- PS動作快速製作可愛餅乾文字效果
- ArcPy自動繪製大量地圖並設定地圖要素:Python地圖Python
- Windows怎麼把視訊變成GIF,動態圖怎麼製作Windows
- 為Ami.BlazorOne新增Docker支援並自動部署BlazorDocker
- 直播平臺製作,文字過多時,自動摺疊顯示檢視更多選項
- windows10電腦怎麼使用迅雷看看播放器製作GIF動圖Windows播放器
- 用Python抓取漫畫並製作mobi格式電子書Python
- Submerge for Mac(字幕製作新增工具)Mac
- 5分鐘學會製作 CSS 波浪文字動畫特效CSS動畫特效
- JS實現將文字轉換為語音並自動播放JS
- 【轉】5分鐘學會製作 CSS 波浪文字動畫特效CSS動畫特效
- Screen To Gif 2.23 釋出,動畫錄製軟體動畫
- 怎麼將視訊製作成GIF動態圖
- Python 短文字自動識別個體是否有自殺傾向Python