10万+的短视频被批量生产了,Python表示不服_10万 的短视频被批量生产了,python表示不服

收集整理了一份《2024年最新Python全套学习资料》免费送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来

如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
img

正文

第一步,我们需要把每一个 GIF 动画转为一段视频。

由于 GIF 动画已经是一段包含很多帧的视频了,没法直接通过 moviepy 库转为一段普通视频。

所以,这里需要对 GIF 动画进行分析,将动画转为「静态帧图片」。

 

def get_gif_frames(gif_path, temp_path):
    “”"
    获取一段GIf图片下的所有静态帧
    get_gif_frames(‘./…/gifs/3.gif’, ‘./…/gif_temp/’)
    :return:
    “”"

# 分析gif图片
    mode = analyseImage(gif_path)[‘mode’]

im = Image.open(gif_path)

i = 1
    p = im.getpalette()
    last_frame = im.convert(‘RGBA’)

try:
        while True:
            # print(“saving %s (%s) frame %d, %s %s” % (gif_path, mode, i, im.size, im.tile))

‘’’
            If the GIF uses local colour tables, each frame will have its own palette.
            If not, we need to apply the global palette to the new frame.
            ‘’’
            if not im.getpalette():
                im.putpalette§

new_frame = Image.new(‘RGBA’, im.size)

‘’’
            Is this file a “partial”-mode GIF where frames update a region of a different size to the entire image?
            If so, we need to construct the new frame by pasting it on top of the preceding frames.
            ‘’’
            if mode == ‘partial’:
                new_frame.paste(last_frame)

new_frame.paste(im, (0, 0), im.convert(‘RGBA’))
            new_frame.save(temp_path + ‘/%s-%d.png’ % (‘’.join(os.path.basename(gif_path).split(‘.’)[:-1]), i), ‘PNG’)

i += 1
            last_frame = new_frame
            im.seek(im.tell() + 1)
    except EOFError:
        # print(‘产生EOFError!!!’)
        pass

另外,我们下载的 GIF 动画的静态帧图片分辨率大概率是不一致的,所以对图片批量修改分辨率「修改分辨率」变的很有必要。

这里将所有图片的分辨率统一修改为 720*1080,在转换的过程中,如果存在空白部分,就使用黑色进行填充。

 

def resize_image(target_image_path, target_size):
    “”"
    调整图片大小,缺失的部分用黑色填充
    :param target_image_path: 图片路径
    :param target_size: 分辨率大小
    :return:
    “”"
    image = Image.open(target_image_path)

iw, ih = image.size  # 原始图像的尺寸
    w, h = target_size  # 目标图像的尺寸
    scale = min(w / iw, h / ih)  # 转换的最小比例

# 保证长或宽,至少一个符合目标图像的尺寸
    nw = int(iw * scale)
    nh = int(ih * scale)

image = image.resize((nw, nh), Image.BICUBIC)  # 缩小图像
    # image.show()

new_image = Image.new(‘RGB’, target_size, (0, 0, 0, 0))  # 生成黑色图像
    # // 为整数除法,计算图像的位置
    new_image.paste(image, ((w - nw) // 2, (h - nh) // 2))  # 将图像填充为中间图像,两侧为灰色的样式
    # new_image.show()

# 覆盖原图片
    new_image.save(target_image_path)

然后,将统一分辨率后的静态帧图片转换为一段普通视频。

在转换为视频之前,我们需要提供一个「合理的转换帧率」来保证视频播放的流畅性。由于最后需要将多段视频合成为一段视频,这里默认指定帧率为 10帧/s。

GIF 动画原始的帧率、播放时长等动画文件属性值可以利用「imgpy」获取到。

 

def get_gif_info(gif_path):
    “”"
    获取gif文件的详细信息
    每一个gif的帧率不一样,有的<10fps;有的>10fps
    :param gif_path:
    :return:
    “”"
    with Img(fp=gif_path) as im:
        # 1.有多少帧
        frame_count = im.frame_count

# 2.图片信息
        # {‘version’: b’GIF89a’, ‘background’: 31, ‘duration’: 70, ‘extension’: (b’NETSCAPE2.0’, 795), ‘loop’: 0}
        duration_pre = im.info.get(‘duration’)

# 根据规律,除以7位实际的播放时长
        duration = duration_pre / 7

# 6.color palette
        # print(im.mode_desc)

# print((frame_count, duration))

# 返回帧率和时长
        return (frame_count / duration), duration

最后,我们利用 moviepy 库中的「ImageSequenceClip」类将这些图片写入到一个视频文件中。

 

def pics_to_video(pics_path, output_path, fps, duration):
    “”"
    图片转为视频
    pics_to_video(‘./…/gif_temp/’, ‘./…/video_temp/temp1.mp4’, 20)
    :param pics_path:
    :param output_path:
    :return:
    “”"
    image_paths = list(map(lambda x: pics_path + x, os.listdir(pics_path)))

# 注意:这里必须进行一次排序,保证所有帧的顺序是一致
    image_paths = sort_strings_with_emb_numbers(image_paths)

# 过滤掉非图片
    image_paths = list(filter(lambda image_path: image_path.endswith(‘.png’), image_paths))

# 图片剪辑类
    clip = ImageSequenceClip(image_paths,
                             fps=fps)

# 写成视频之前,需要把gif都转成同一个分辨率
    clip.write_videofile(output_path)

循环上面的操作,就可以将所有的 GIF 动画转换为一个普通视频文件。

第二步是将所有的视频文件进行剪辑,写入一个单独的文件中。利用 moviepy 库下面的 「 VideoFileClip」可以非常快捷方便地完成这一操作。

 

def compound_a_video(self, videos_path):
        “”"
        合成一个视频
        :param videos_output:视频集合的完整目录
        :return:
        “”"
        # 定义一个数组
        L = []

for video_path in videos_path:
            # 载入视频
            video = VideoFileClip(video_path)
            # 添加到数组
            L.append(video)

# 拼接视频
        final_clip = concatenate_videoclips(L)

# 生成目标视频文件
        final_clip.to_videofile(self.video_output_temp, fps=self.fps, remove_temp=False)

最后一步是往视频中添加背景音乐。

文末有福利领取哦~

👉一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。img

👉二、Python必备开发工具

img
👉三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
img

👉 四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
img

👉五、Python练习题

检查学习结果。
img

👉六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
img

img

👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
8e9da4805b1a3f9.png)

👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

如果你需要这些资料,可以添加V无偿获取:hxbc188 (备注666)
[外链图片转存中…(img-s8eNSZST-1713786422284)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值