赞
踩
一、 代码
import os import cv2 import moviepy.editor as mp from PIL import Image, ImageFont, ImageDraw # 图片像素点字符数组 ASCII_CHAR = list("$B%314567890*WM#oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:oa+>!:+. ") # 视频文件 .mp4 要保存的路径 SAVE_PATH = r"E:\b\node.js\complete-node-bootcamp\1-node-farm\learning" # 视频文件 .mp4 转换为 帧图片 所在文件夹路径 CACHE_PATH = os.path.join(SAVE_PATH, "Cache") # 帧图片 转换为 字符图片 所在文件夹路径 CHARACTER_PATH = os.path.join(SAVE_PATH, "Character") def get_ascii(r, g, b, alpha=256): """ 将图片的像素点转换为字符数组中的字符 :param r: 红 :param g: 绿 :param b: 蓝 :param alpha: 亮度 :return: 返回标准灰度数值的 ASCII_CHAR 数组 """ if alpha == 0: return "" length = len(ASCII_CHAR) gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) unit = (256.0 + 1) / length return ASCII_CHAR[int(gray/unit)] def txt2image(file_name): """ 将 .jpg 图片 重新绘制为 字符图片 :param file_name: 输出文件名称 :return: 无返回值 """ img = Image.open(os.path.join(CACHE_PATH, file_name)).convert("RGB") img_width = img.width img_height = img.height img = img.resize((int(img.width / 100 * 100), int(img.height / 100 * 100)), Image.NEAREST) raw_width = img.width raw_height = img.height width = int(raw_width / 6) height = int(raw_height / 15) img = img.resize((width, height), Image.NEAREST) txt = "" colors = [] for y in range(height): for x in range(width): pixel = img.getpixel((x, y)) colors.append((pixel[0], pixel[1], pixel[2])) if len(pixel) == 4: txt += get_ascii(pixel[0], pixel[1], pixel[2], pixel[3]) else: txt += get_ascii(pixel[0], pixel[1], pixel[2]) txt += "\n" colors.append((255, 255, 255)) img_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255)) new_img = ImageDraw.Draw(img_txt) font = ImageFont.load_default().font x = y = 0 font_w, font_h = font.getsize(txt[1]) font_h *= 1.37 for row in range(len(txt)): if txt[row] == "\n": x += font_h y = -font_w new_img.text((y, x), txt[row], fill=colors[row]) y += font_w img_txt = img_txt.resize((img_width, img_height), Image.NEAREST) img_txt.save(os.path.join(CHARACTER_PATH, file_name)) def video2jpg(file_path): """ 将 .mp4 视频文件拆分成 .jpg 帧图片 :param file_path: 视频所在路径 :return: 返回捕捉到的视频帧图片集 """ vc = cv2.VideoCapture(file_path) if vc.isOpened(): r, frame = vc.read() if not os.path.exists(CACHE_PATH): os.mkdir(CACHE_PATH) os.chdir(CACHE_PATH) else: r = False convert_name = 0 while r: frame = frame[0:1080, 272:2188] # 图片裁剪 # frame = cv2.resize(frame, (imgs_width, imgs_height)) # 图片大小重置 cv2.imwrite(str(convert_name) + ".jpg", frame) txt2image(str(convert_name) + ".jpg") r, frame = vc.read() convert_name += 1 print("当前视频 {} 转换的 .jpg 图片数量为: {}\n".format(file_path.split("\\")[-1], convert_name)) return vc def jpg2video(outfile_name, fps): """ 将图片合成视频 :param outfile_name: 输出文件名 :param fps: 帧频率 :return: 无返回值 """ fourcc = cv2.VideoWriter_fourcc(*"MP4V") # .mp4 格式的视频 images = os.listdir(CACHE_PATH) img0 = Image.open(os.path.join(CACHE_PATH, images[0])) imgs_width = img0.width imgs_height = img0.height outfile_path = os.path.join(SAVE_PATH, outfile_name + ".mp4") vw = cv2.VideoWriter(outfile_path, fourcc, fps, (imgs_width, imgs_height)) # os.chdir(CACHE_PATH) # 输出经过处理后的 合成的 原来的 无声视频 os.chdir(CHARACTER_PATH) # 输出处理后的字符图片合成的无声视频 for image in range(len(images)): frame = cv2.imread(str(image) + ".jpg") vw.write(frame) vw.release() def video2mp3(file_path, outfile_name): """ 视频文件转换为音频文件 :param file_path: 视频文件所在路径 :param outfile_name: 输出的音频文件名 :return: 无返回值 """ outfile_path = os.path.join(SAVE_PATH, outfile_name + ".mp3") if os.path.exists(outfile_path): os.remove(outfile_path) os.chdir(SAVE_PATH) video_clip = mp.VideoFileClip(file_path) video_clip.audio.write_audiofile(os.path.join(SAVE_PATH, outfile_name + ".mp3")) def composite_video_and_mp3(video_path, mp3_path, outfile_name): """ 将视频文件和音频文件合成起来 :param avi_file: 视频文件 :param mp3_file: 音频文件 :param outfile_name: 输出的视频文件名 :return: 无返回值 """ outfile_path = os.path.join(SAVE_PATH, outfile_name + ".mp4") if os.path.exists(outfile_path): os.remove(outfile_path) os.chdir(SAVE_PATH) video_clip = mp.VideoFileClip(video_path) mp3_clip = mp.AudioFileClip(mp3_path) composite_clip = video_clip.set_audio(mp3_clip) composite_clip.write_videofile(outfile_path) def remove_dir(file_path): """ 删除中间文件夹 :param path: 文件夹路径 :return: 无返回值 """ if os.path.exists(file_path): if os.path.isdir(file_path): files = os.listdir(file_path) for file in files: path = os.path.join(file_path, file) if os.path.isdir(path): remove_dir(path) elif os.path.isfile(path): os.remove(path) os.rmdir(file_path) return elif os.path.isfile(file_path): os.remove(file_path) return if __name__ == '__main__': # 视频文件所在路径 file_path = r"E:\b\node.js\complete-node-bootcamp\1-node-farm\learning\op.mp4" # 视频文件名 file_name = file_path.split("\\")[-1] print("********* 开始视频转换 *********\n") print("********* 1. 视频转换为图片 *********\n") vc = video2jpg(file_path) FPS = vc.get(cv2.CAP_PROP_FPS) vc.release() print("当前视频 {} 转换为图片成功!\n".format(file_name)) # exit() print("********* 2. 图片转换为视频 *********\n") outfile_name = file_path.split("\\")[-1].split(".")[0] print(outfile_name + ".mp4 开始生成...\n") jpg2video(outfile_name, FPS) print(outfile_name + ".mp4 生成完毕!\n") # exit() print("********* 3. 视频转换为音频 *********\n") print(outfile_name + ".mp3 开始生成...\n") video2mp3(file_path, outfile_name) print("\n" + outfile_name + ".mp3 生成完毕!\n") # exit() print("********* 4. 视频和音频合成为视频 *********\n") print(outfile_name + ".mp4 开始合成...\n") composite_video_and_mp3(os.path.join(SAVE_PATH, outfile_name + ".mp4"), os.path.join(SAVE_PATH, outfile_name + ".mp3"), outfile_name + "_new") print(outfile_name + ".mp4 合成完毕!\n") print("当前视频 {} 转换为新视频 {} 成功!\n".format(file_name, outfile_name + "_new" + ".mp4")) # exit() remove_dir(CACHE_PATH) remove_dir(CHARACTER_PATH)
二、示例
op_new
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。