主题
生成视频序列帧
python
import os
from PIL import Image
import shutil
import json
import os,time,threading
fps_video_dir = 'fps_video'
def get_size(filename):
# Obtain the file size: KB
size = os.path.getsize(filename)
return size / 1024
def compress_image(img_path, out_path, radio=0.05,mb=50, step=5, quality=100):
"""不改变图片尺寸压缩图像大小
:param img_path: 压缩图像读取地址
:param out_path: 压缩图像存储地址
:param mb: 压缩目标,KB
:param step: 每次调整的压缩比率
:param quality: 初始压缩比率
:return: 压缩文件地址,压缩文件大小
"""
o_size = get_size(img_path)
if o_size < mb:
img = Image.open(img_path)
img = img.convert('RGB')
img.save(out_path, quality=quality)
return Image.open(img_path)
mb = o_size * radio
img = Image.open(img_path)
while o_size > mb:
img = Image.open(img_path)
img = img.convert('RGB')
img.save(out_path, quality=quality)
if quality - step < 0:
break
quality -= step
o_size = get_size(out_path)
print('File size: ' ,img_path,int(o_size))
return img
def mp4_to_png(mp4):
cmd = f'ffmpeg -i {mp4} -r 24 -f image2 ./{fps_video_dir}/img%05d.png'
print(cmd)
os.system(cmd)
def get_file_cnt(dir):
cnt = 0
for item in os.listdir(dir):
if item.endswith(".png"):
cnt += 1
return cnt
def generate_json(output_dir):
cnt = get_file_cnt(fps_video_dir)
data = json.dumps(dict(imgCnt=cnt))
with open(os.path.join(output_dir,'config.json'),'w+') as file:
file.write(data)
def compress(input_dir,output_dir):
for item in os.listdir(input_dir):
if not item.endswith(".png"):
continue
input_path = os.path.join(input_dir,item)
out_jpg_path = os.path.join(output_dir,item.replace(".png",".jpg"))
out_png_path = os.path.join(output_dir,item)
compress_image(input_path,out_jpg_path)
if not os.path.exists(out_jpg_path):
raise Exception("文件不存在",out_jpg_path)
# continue
o_size = os.path.getsize(out_jpg_path) // 1024
# print(o_size)
shutil.copyfile(out_jpg_path,out_png_path)
os.remove(out_jpg_path)
def compress_t(images,input_dir,output_dir):
for item in images:
if not item.endswith(".png"):
continue
input_path = os.path.join(input_dir,item)
out_jpg_path = os.path.join(output_dir,item.replace(".png",".jpg"))
out_png_path = os.path.join(output_dir,item)
compress_image(input_path,out_jpg_path)
if not os.path.exists(out_jpg_path):
raise Exception("文件不存在",out_jpg_path)
# continue
o_size = os.path.getsize(out_jpg_path) // 1024
# print(o_size)
shutil.copyfile(out_jpg_path,out_png_path)
os.remove(out_jpg_path)
def get_file_list(dir):
ret = []
for item in os.listdir(dir):
if item.endswith(".png"):
ret.append(item)
return ret
def compress_bat(fps_video_dir,output_dir):
# group
group_cnt = 5
file_list = get_file_list(fps_video_dir)
totle = len(file_list)
padding = int(totle / group_cnt)+1
image_list = []
for i in range(0,len(file_list),padding):
b=file_list[i:i+padding]
print(b)
image_list.append(b)
cnt = 0
for item in image_list:
cnt += len(item)
print (len(image_list),cnt)
thread_list = []
for thread_idx in range(group_cnt):
thread_list.append(threading.Thread(target=compress_t, args=(image_list[thread_idx], fps_video_dir,output_dir,)))
for item in thread_list:
item.start()
for item in thread_list:
item.join()
def check_file_cnt(output_dir):
src_cnt = get_file_cnt(fps_video_dir)
dst_cnt = get_file_cnt(output_dir)
return src_cnt,dst_cnt
def get_ts():
now = int(time.time())
timeArray = time.localtime(now)
ts = time.strftime("%Y%m%d%H%M%S", timeArray)
print (ts)
return ts
def main(mp4):
start = int(get_ts())
if not os.path.exists(fps_video_dir):
os.makedirs(fps_video_dir)
# clean input dir
for item in os.listdir(fps_video_dir):
os.remove(os.path.join(fps_video_dir,item))
mp4_to_png(mp4)
output_dir = os.path.basename(mp4).replace(".mp4",'')
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# clean output dir
for item in os.listdir(output_dir):
os.remove(os.path.join(output_dir,item))
generate_json(output_dir)
# compress(fps_video_dir,output_dir)
compress_bat(fps_video_dir,output_dir)
src_cnt,dst_cnt = check_file_cnt(output_dir)
end = int(get_ts())
print('用时',(end-start))
if src_cnt != dst_cnt:
print(src_cnt,dst_cnt)
raise Exception("压缩过程中,图片数不匹配")
if __name__ == '__main__':
# compress_image('fps_video/img01272.png','1c799f206d6d481a98cadf6d581ffb40/img01272.jpg')
main('./1c799f206d6d481a98cadf6d581ffb40.mp4')