需求:
在一个大文件夹里(第一层),有很多小文件夹(第二层),每个小文件夹里有很多相同像素尺寸的图片,需要合成视频,不需要那么花里胡哨的,只是简单的视频即可,哪怕只有简单的图片切换,一个图片显示一秒钟就可以
代码粗狂实现如下:写的过程中很多不知道,就写了很多试错的备注,如果不喜欢,最下面有一个简洁版的,可以直接复制
import os
import cv2
import shutil
from ntpath import join
from tkinter import messagebox
from tkinter import filedialog
from pypinyin import lazy_pinyin # 用于汉字转英文
from os.path import join as path_join
# import numpy # cv2无法识别中文,需要numpy,结果很明显失败了,可以显示了,但是无法写入视频文件,算了,还是老老实实改英文吧
# 编译环境:Python3.9,Win10系统
# 需要额外安装的库:cv2、pypinyin
# 根据原图的数量,进行批量复制出来,从而达到延迟的效果
# 请选择文件夹的之前,尽量将文件放在 D、E等盘符,防止用户名是中文的情况,会报错
messagebox.showinfo('友情提示!','请选择文件夹的之前,尽量将文件放在 D、E等盘符,\n\n 防止用户名是中文的情况,会报错!!!')
messagebox.showerror('友情提示!','现在您确定您的文件夹路径是没有中文的是么? \n\n 我指的是第一层文件夹之前的路径')
messagebox.showwarning('友情提示!','如果你确定没有问题,OK,你可以继续了,\n\n 如果异常,你现在还有最后一次机会停止程序!')
path = filedialog.askdirectory()
# path = r'C:\Users\Administrator\Desktop\sts\图片'
path_new = str(path) + '1'
def rename_folder():
for i in os.listdir(path_new):
for k in os.listdir(path_join(path_new,i)):
os.rename(path_join(path_new,i,k),path_join(path_new,i,k).replace('.png','.jpg'))
for k in os.listdir(path_join(path_new,i)):
os.rename(path_join(path_new,i,k),path_join(path_new,i,'_'.join(lazy_pinyin(k))))
os.rename(path_join(path_new,i),path_join(path_new,'_'.join(lazy_pinyin(i))))
os.rename(path_new,'_'.join(lazy_pinyin(path_new)))
# return path_new
print('_'.join(lazy_pinyin(path_new)))
return '_'.join(lazy_pinyin(path_new))
def right_to_left_find(string,string_find):
finally_num = string[::-1].find(string_find)+1 # 这里+1 是为了把搜索的字符也加上去
# print(f'倒序之后的第一个出现的位置:{finally_num}')
result = string[len(string)-finally_num:]
# print(f'从右向左查找的结果为:{result}')
return result
def copt_allfile():
shutil.copytree(path,path_new) # copytree 可以递归里面所有文件,相当于是复制文件夹
for i in os.listdir(path_new):
k_value = 0
for k in os.listdir(path_join(path_new,i)):
if not os.path.isdir(path_join(path_new,i,k)):
for j in range(30):
# for j in range(1,30 * len(os.listdir(path_join(path_new,i))) + 1):
# print(path_join(i,k),' →→→ ',str(k_value) + right_to_left_find(k,'.'))
shutil.copy2(path_join(path_new,i,k),path_join(path_new,i,str(k_value) + right_to_left_find(k,'.')))
k_value += 1
os.remove(path_join(path_new,i,k)) # 删除原来的图片
def creade_video(path_new): # 这里要加入一个形参,不然就会报错: local variable 'path_new' referenced before assignment 局部变量path_new在赋值前被引用
path = path_new
# 获取每个文件夹里面的第一个图片的路径, 用于后面获取尺寸使用
for i in os.listdir(path):
path_new = path_join(path,i)
#获取一张图片的宽高作为视频的宽高
# image = numpy.fromfile(path_join(path_new,os.listdir(path_new)[0]),dtype=numpy.uint8)
# image=cv2.imdecode(image,-1) # cv2无法识别中文,需要numpy 的 fromfile 然后使用 cv2的 imdecode 转码识别,,事实证明,图片是可以读取了,但是视频还是无法正常播放,还是老老实实改英文吧
image=cv2.imread(path_join(path_new,os.listdir(path_new)[0]))
cv2.imshow("new window", image) #显示图片
cv2.waitKey(1000) # 0或者不写参数,代表不关闭,写1000,代表1s后关闭
image_info=image.shape
height=image_info[0]
width=image_info[1]
size=(height,width)
print(size)
fps=30
fourcc=cv2.VideoWriter_fourcc(*"mp4v")
video = cv2.VideoWriter(path_join(path_new,'join_photo.mp4'), cv2.VideoWriter_fourcc(*"mp4v"), fps, (width,height)) #创建视频流对象-格式一
# video = cv2.VideoWriter('ss.mp4', cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), fps, (width,height)) #创建视频流对象-格式二
"""
参数1 即将保存的文件路径
参数2 VideoWriter_fourcc为视频编解码器
fourcc意为四字符代码(Four-Character Codes),顾名思义,该编码由四个字符组成,下面是VideoWriter_fourcc对象一些常用的参数,注意:字符顺序不能弄混
cv2.VideoWriter_fourcc('I', '4', '2', '0'),该参数是YUV编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc('P', 'I', 'M', 'I'),该参数是MPEG-1编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'),该参数是MPEG-4编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc('T', 'H', 'E', 'O'),该参数是Ogg Vorbis,文件名后缀为.ogv
cv2.VideoWriter_fourcc('F', 'L', 'V', '1'),该参数是Flash视频,文件名后缀为.flv
cv2.VideoWriter_fourcc('m', 'p', '4', 'v') 文件名后缀为.mp4
参数3 为帧播放速率
参数4 (width,height)为视频帧大小
"""
for i in range(len(os.listdir(path_new))):
file_name = path_join(path_new,str(i) + '.jpg')
print(file_name)
image=cv2.imread(file_name)
video.write(image) # 向视频文件写入一帧--只有图像,没有声音
if __name__ == "__main__":
copt_allfile()
creade_video(rename_folder()) # 获取返回值
# 写在最后的话,如果分辨率不同,那么在视频中,是无法加载出来的,就是根本看不到...
# creade_video(path_new) # 获取返回值
如果你不喜欢上面太多废话,可以看看这里的代码,
都是一样的,去掉了试错的代码和注释
import os
import cv2
import shutil
from ntpath import join
from tkinter import messagebox
from tkinter import filedialog
from pypinyin import lazy_pinyin # 用于汉字转英文
from os.path import join as path_join
# 编译环境:Python3.9,Win10系统
# 需要额外安装的库:cv2、pypinyin
# 根据原图的数量,进行批量复制出来,从而达到延迟的效果
# 请选择文件夹的之前,尽量将文件放在 D、E等盘符,防止用户名是中文的情况,会报错
messagebox.showinfo('友情提示!','请选择文件夹的之前,尽量将文件放在 D、E等盘符,\n\n 防止用户名是中文的情况,会报错!!!')
messagebox.showerror('友情提示!','现在您确定您的文件夹路径是没有中文的是么? \n\n 我指的是第一层文件夹之前的路径')
messagebox.showwarning('友情提示!','如果你确定没有问题,OK,你可以继续了,\n\n 如果异常,你现在还有最后一次机会停止程序!')
path = filedialog.askdirectory()
path_new = str(path) + '1'
def rename_folder():
for i in os.listdir(path_new):
for k in os.listdir(path_join(path_new,i)):
os.rename(path_join(path_new,i,k),path_join(path_new,i,k).replace('.png','.jpg'))
for k in os.listdir(path_join(path_new,i)):
os.rename(path_join(path_new,i,k),path_join(path_new,i,'_'.join(lazy_pinyin(k))))
os.rename(path_join(path_new,i),path_join(path_new,'_'.join(lazy_pinyin(i))))
os.rename(path_new,'_'.join(lazy_pinyin(path_new)))
return '_'.join(lazy_pinyin(path_new))
def right_to_left_find(string,string_find):
finally_num = string[::-1].find(string_find)+1 # 这里+1 是为了把搜索的字符也加上去
result = string[len(string)-finally_num:]
return result
def copt_allfile():
shutil.copytree(path,path_new) # copytree 可以递归里面所有文件,相当于是复制文件夹
for i in os.listdir(path_new):
k_value = 0
for k in os.listdir(path_join(path_new,i)):
if not os.path.isdir(path_join(path_new,i,k)):
for j in range(30):
shutil.copy2(path_join(path_new,i,k),path_join(path_new,i,str(k_value) + right_to_left_find(k,'.')))
k_value += 1
os.remove(path_join(path_new,i,k)) # 删除原来的图片
def creade_video(path_new): # 这里要加入一个形参,不然就会报错: local variable 'path_new' referenced before assignment 局部变量path_new在赋值前被引用
path = path_new
for i in os.listdir(path):
path_new = path_join(path,i)
image=cv2.imread(path_join(path_new,os.listdir(path_new)[0]))
cv2.imshow("new window", image) #显示图片
cv2.waitKey(1000) # 0或者不写参数,代表不关闭,写1000,代表1s后关闭
image_info=image.shape
height=image_info[0]
width=image_info[1]
size=(height,width)
print(size)
fps=30
fourcc=cv2.VideoWriter_fourcc(*"mp4v")
video = cv2.VideoWriter(path_join(path_new,'join_photo.mp4'), cv2.VideoWriter_fourcc(*"mp4v"), fps, (width,height)) #创建视频流对象-格式一
for i in range(len(os.listdir(path_new))):
file_name = path_join(path_new,str(i) + '.jpg')
print(file_name)
image=cv2.imread(file_name)
video.write(image) # 向视频文件写入一帧--只有图像,没有声音
if __name__ == "__main__":
copt_allfile()
creade_video(rename_folder()) # 获取返回值
# 写在最后的话,如果分辨率不同,那么在视频中,是无法加载出来的,就是根本看不到...