美文网首页
制作图片墙

制作图片墙

作者: ThomasYoungK | 来源:发表于2018-08-18 17:24 被阅读40次
今天我用各种工具组合,制作了一个图片墙,效果如下图: wall.jpg

大致过程如下

  1. 去youtube下载视频,https://www.youtube.com/watch?v=9_OSXkatlEs
  2. 用正则表达式解析视频的时长,使用了ffmepg,安装方法是brew install ffmpeg
  3. 根据时长和想截取的图片数量,确定fps(截图频率),使用ffmepg截图并保存图片
  4. 使用pillow库将图片遍历,组合成一张大图

直接上代码:

import PIL
from PIL import Image, ImageFilter, ImageDraw, ImageFont
from random import randint
import glob
import ffmpeg
import subprocess
import re
from decimal import Decimal

video_path = '../data/video.mp4'
origin_cat = '../data/origin_cat.jpeg'
back_ground_path = '../data/back_ground.png'
frame_path = '../frames'

def get_video_length(path):
    """ffmpeg -i file_path生成的字符串中含有视频的时长:
    .....
    Duration: 00:03:58.98, start: 0.000000, bitrate: 709 kb/s
    .....
    通过正则表达式将其中的时分秒提取出来,转化为秒
    """
    process = subprocess.Popen(['/usr/local/bin/ffmpeg', '-i', path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout, stderr = process.communicate()
    matches = re.search(r"Duration:\s{1}(?P<hours>\d+):(?P<minutes>\d+):(?P<seconds>\d+\.\d+),", stdout.decode('utf-8'),
                        re.DOTALL).groupdict()

    hours = Decimal(matches['hours'])
    minutes = Decimal(matches['minutes'])
    seconds = Decimal(matches['seconds'])

    total = 0
    total += 60 * 60 * hours
    total += 60 * minutes
    total += seconds
    return float(total)


def capture_video(video_path, num):
    """将视频截取num张图片
    每10秒生成一个图片的语法
    ffmpeg -i ./data/video.mp4 -vf fps=1/10 ./frames/pic%4d.jpg
    """
    seconds = get_video_length(video_path)
    pfs = num / seconds  # 计算要截取num张图片,fps是多少(每秒几张图)
    cmd = f'ffmpeg -i {video_path} -vf fps={pfs} ../frames/pic%4d.jpg'  # 截取num张图片,放到'../frames/'目录下
    subprocess.run(cmd, shell=True)


def plot_pic_wall(saved_name):
    w_num = 10
    h_num = 10
    pics = sorted(glob.glob(frame_path + '/*'))
    im = Image.open(pics[0])
    w, h = im.size
    print(w, h, w*h)
    big_img = Image.new('RGB', (w * 10, h * 10), (255, 255, 255))
    positions = [(w * j, h * i) for i in range(w_num) for j in range(h_num)]
    count = 0
    for pic, position in zip(pics, positions):
        count += 1
        img = Image.open(pic)
        big_img.paste(img, position)
        if count > 0 and count % 10 == 0:
            big_img.save(saved_name)
            big_img = Image.open(saved_name)
            print('保存了一行')
    big_img = big_img.resize((w*5, h*5), PIL.Image.ANTIALIAS)  # 图像太大了,还是做小一点吧
    big_img.save(saved_name)
    print("图片墙保存成功")

相关文章

网友评论

      本文标题:制作图片墙

      本文链接:https://www.haomeiwen.com/subject/uzvfiftx.html