wangzhibo
2025-07-30 c706a69abfe9bae1322adbd344dfdaae37cdf564
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import os
import cv2
import numpy as np
from PIL import Image
import argparse
 
def is_image_file(filename):
    return filename.lower().endswith(('.jpg', '.jpeg', '.png'))
 
def resize_and_pad_cv(image, size=(1280, 720)):
    ih, iw = image.shape[:2]
    target_w, target_h = size
 
    scale = min(target_w / iw, target_h / ih)
    new_w = int(iw * scale)
    new_h = int(ih * scale)
    resized = cv2.resize(image, (new_w, new_h))
 
    top = (target_h - new_h) // 2
    bottom = target_h - new_h - top
    left = (target_w - new_w) // 2
    right = target_w - new_w - left
 
    padded = cv2.copyMakeBorder(resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])
    return padded
 
def get_first_frame(video_path):
    cap = cv2.VideoCapture(video_path)
    success, frame = cap.read()
    cap.release()
    return frame if success else None
 
def check_and_process_individual_cover(mp4_path):
    base = os.path.splitext(mp4_path)[0]
    for ext in ['.jpg', '.jpeg', '.png']:
        img_path = base + ext
        if os.path.exists(img_path):
            try:
                with Image.open(img_path) as img:
                    w, h = img.size
                    if w < 720:
                        os.remove(img_path)
                        print(f"删除低分辨率封面图: {img_path}")
                        return False  # 继续处理 mp4
                    else:
                        print(f"已有封面图,裁剪为1280x720并跳过视频: {img_path}")
                        processed = resize_and_pad_cv(cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR))
                        #cv2.imwrite(img_path, processed)
                        Image.fromarray(cv2.cvtColor(processed, cv2.COLOR_BGR2RGB)).save(img_path)
 
                        return True  # 不再处理该 mp4
            except Exception as e:
                print(f"处理封面图出错 {img_path}: {e}")
                return False
    return False  # 没有封面图,继续处理 mp4
 
def process_medias(folder):
    for root, _, files in os.walk(folder):
        for file in files:
            if file.lower().endswith('.mp4'):
                video_path = os.path.join(root, file)
                skip = check_and_process_individual_cover(video_path)
                if skip:
                    continue
                frame = get_first_frame(video_path)
                if frame is None:
                    print(f"无法读取视频帧: {video_path}")
                    continue
                output_img = resize_and_pad_cv(frame)
                output_path = os.path.splitext(video_path)[0] + "_cover.jpg"
                #cv2.imwrite(output_path, output_img)
                Image.fromarray(cv2.cvtColor(output_img, cv2.COLOR_BGR2RGB)).save(output_path)
                print(f"生成封面图: {output_path}")
 
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="处理mp4封面图")
    parser.add_argument("folder", help="包含视频的文件夹")
    args = parser.parse_args()
    process_medias(args.folder)