python将图片生成gif图
方法一
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: 中英文文字轨迹GIF
# Author: yunhgu
# Date: 2022/1/6 10:14
# Description:
# -------------------------------------------------------------------------------
import copy
import logging
from collections import defaultdict
from pathlib import Path
from time import strftime, localtime, time
from traceback import format_exc
import cv2
import imageio
import numpy as np
def check_exist(path):
"""
@param path: 文件或者文件夹路径
@return: True/False
"""
return Path(path).exists() and path != ""
def log(log_name: str, p_type=""):
"""
@param log_name:log文件名字
@param p_type:输出类型
@return:日志对象
"""
journal = logging.getLogger(log_name)
journal.setLevel(logging.INFO)
log_file = f"{log_name}{strftime('%Y%m%d%H', localtime(time()))}.log"
format_content = '%(message)s'
if p_type == "time":
format_content = '%(asctime)s - %(levelname)s: %(message)s'
formatter = logging.Formatter(format_content)
# 创建日志文件对象
handler = logging.FileHandler(log_file, encoding="utf-8", mode="w")
handler.setLevel(logging.INFO)
handler.setFormatter(formatter)
# 创建日志流对象
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
# 添加文件和输出流到日志对象
journal.addHandler(handler)
journal.addHandler(console)
return journal
logger = log("中英文文字轨迹GIF", p_type="time")
def read_txt(file_path):
with open(file_path, encoding="utf-8", mode="r") as f:
return f.read()
def get_coordinates(file_path):
content_list = read_txt(file_path).strip("(").strip(")").split(",")
coordinates_dic = defaultdict(list)
name = 0
x_max = 0
y_max = 0
for index in range(len(content_list) - 1)[::2]:
x = int(content_list[index])
y = int(content_list[index + 1])
if x > x_max:
x_max = x
if y > y_max:
y_max = y
if [x, y] == [-1, 0]:
name += 1
continue
coordinates_dic[name].append([x, y])
return coordinates_dic, x_max, y_max
def draw_gif(output_file, coordinates_dic, x_max, y_max):
image = np.zeros((y_max, x_max, 3), dtype=np.uint8)
buff = []
for coordinates in coordinates_dic.values():
for coordinate in coordinates:
cv2.circle(image, coordinate, 1, (255, 255, 255), -1)
img = copy.deepcopy(image)
buff.append(img)
print(f"{output_file.name}:生成gif中")
imageio.mimsave(output_file, buff, 'GIF', duration=0.1)
def convert(file, output_file):
coordinates_dic, x_max, y_max = get_coordinates(file)
draw_gif(output_file, coordinates_dic, x_max, y_max)
def main(input_path, output_path):
txt_file_list = [file for file in input_path.rglob("*.txt")]
for file in txt_file_list:
try:
output_file = output_path.joinpath(file.relative_to(input_path))
output_file = output_file.parent.joinpath(f"{output_file.stem}-.gif")
output_file.parent.mkdir(parents=True, exist_ok=True)
convert(file, output_file)
except Exception as e:
logger.error(f"{file}运行失败,跳过这个文件。{e}\n{format_exc()}")
if __name__ == '__main__':
while True:
print("**** start ****")
input_folder = input("请输入轨迹坐标txt文件夹:").strip("\"")
output_folder = input("请输入结果保存文件夹:").strip("\"")
if check_exist(input_folder) and check_exist(output_folder):
try:
start = time()
main(Path(input_folder), Path(output_folder))
print(time() - start)
except Exception as ee:
logger.error(f"{format_exc()}:{ee}")
finally:
print("**** finished ****")
c = input("请输入q(不区分大小写)退出,按其他任意键继续!!!")
if c.lower() == "q":
break
else:
logger.error("输入的路径不存在,请检查后重新输入!!!")
continue
方法二
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: 中英文文字轨迹GIF
# Author: yunhgu
# Date: 2022/1/6 10:14
# Description:
# -------------------------------------------------------------------------------
import logging
import shutil
import subprocess
from collections import defaultdict
from pathlib import Path
from time import strftime, localtime, time
from traceback import format_exc
import cv2
import numpy as np
from ffmpy3 import FFmpeg
def check_exist(path):
"""
@param path: 文件或者文件夹路径
@return: True/False
"""
return Path(path).exists() and path != ""
def log(log_name: str, p_type=""):
"""
@param log_name:log文件名字
@param p_type:输出类型
@return:日志对象
"""
journal = logging.getLogger(log_name)
journal.setLevel(logging.INFO)
log_file = f"{log_name}{strftime('%Y%m%d%H', localtime(time()))}.log"
format_content = '%(message)s'
if p_type == "time":
format_content = '%(asctime)s - %(levelname)s: %(message)s'
formatter = logging.Formatter(format_content)
# 创建日志文件对象
handler = logging.FileHandler(log_file, encoding="utf-8", mode="w")
handler.setLevel(logging.INFO)
handler.setFormatter(formatter)
# 创建日志流对象
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
# 添加文件和输出流到日志对象
journal.addHandler(handler)
journal.addHandler(console)
return journal
logger = log("中英文文字轨迹GIF", p_type="time")
def read_txt(file_path):
with open(file_path, encoding="utf-8", mode="r") as f:
return f.read()
def get_coordinates(file_path):
content_list = read_txt(file_path).strip("(").strip(")").split(",")
coordinates_dic = defaultdict(list)
name = 0
x_max = 0
y_max = 0
for index in range(len(content_list) - 1)[::2]:
x = int(content_list[index])
y = int(content_list[index + 1])
if x > x_max:
x_max = x
if y > y_max:
y_max = y
if [x, y] == [-1, 0]:
name += 1
continue
coordinates_dic[name].append([x, y])
return coordinates_dic, x_max, y_max
def generate_txt(file_list):
content = "file " + "file ".join(file_list)
with open("temp.txt", encoding="utf-8", mode="w") as f:
f.write(content.replace("\\", "\\\\"))
def draw_gif(output_file, coordinates_dic, x_max, y_max):
image = np.zeros((y_max, x_max, 3), dtype=np.uint8)
index = 1
temp_folder = output_file.parent.joinpath("Temp")
temp_folder.mkdir(parents=True, exist_ok=True)
temp_file_list = []
for coordinates in coordinates_dic.values():
for coordinate in coordinates:
cv2.circle(image, coordinate, 1, (255, 255, 255), -1)
temp_img = temp_folder.joinpath(f"{output_file.stem}-{index}.png")
cv2.imencode(".png", image)[1].tofile(temp_img)
temp_file_list.append(f"{str(temp_img)}\n")
index += 1
# generate_txt(temp_file_list)
fps = len(temp_file_list)//3
FFmpeg(
inputs={f"{temp_folder}\\{output_file.stem}-%d.png": ['-r', '5']},
outputs={
'output.gif': ['-filter_complex', 'split[v1][v2];[v1]palettegen[pal];[v2][pal]paletteuse=dither=sierra2_4a',
'-y']}
).run(stdout=subprocess.PIPE)
shutil.rmtree(temp_folder)
# os.remove("temp.txt")
def convert(file, output_file):
coordinates_dic, x_max, y_max = get_coordinates(file)
draw_gif(output_file, coordinates_dic, x_max, y_max)
def main(input_path, output_path):
txt_file_list = [file for file in input_path.rglob("*.txt")]
for file in txt_file_list:
try:
output_file = output_path.joinpath(file.relative_to(input_path))
output_file = output_file.parent.joinpath(f"{output_file.stem}.gif")
output_file.parent.mkdir(parents=True, exist_ok=True)
convert(file, output_file)
except Exception as e:
logger.error(f"{file}运行失败,跳过这个文件。{e}\n{format_exc()}")
if __name__ == '__main__':
while True:
print("**** start ****")
input_folder = input("请输入轨迹坐标txt文件夹:").strip("\"")
output_folder = input("请输入结果保存文件夹:").strip("\"")
if check_exist(input_folder) and check_exist(output_folder):
try:
start = time()
main(Path(input_folder), Path(output_folder))
print(time()-start)
except Exception as ee:
logger.error(f"{format_exc()}:{ee}")
finally:
print("**** finished ****")
c = input("请输入q(不区分大小写)退出,按其他任意键继续!!!")
if c.lower() == "q":
break
else:
logger.error("输入的路径不存在,请检查后重新输入!!!")
continue
不论你在什么时候开始,重要的是开始之后就不要停止。
不论你在什么时候结束,重要的是结束之后就不要悔恨。