python可以实现什么炫酷图形吗_如何把图片变得炫酷多彩,Python教你这样实现!...

有趣的图片

如何能让图片变得好玩?首先需要让它动起来!可如果是多张图片,我们还可以将其拼接起来组成gif动图,可一张图怎么玩?记得之前写过一个小练习,把一张图片拆分成九宫格的分片图。那么,能否由此下手整出点花样呢?先来看看最终实现的两种方案吧:

轮播闪现

20190923141454827.gif

分块加载

20190923141529618.gif

实现分析

命令行交互

首先,看过上面的两张动图,细心的朋友会发现,动图将原有的图片拆分为了25块,然后进行特定的拼接。那么只能拆分成25么,模式又该怎么选择呢?此时我们需要引入一个模块argparse,它是专门用作命令行参数配置的库。之前专门写过一篇针对该模块的总结文章,大家可以去看看:

对于python命令行,你应该这么做才专业

好了,回到当下内容,我们需要针对三项进行配置,图片路径、gif展示方式、拆分图片数量

# -*- coding: utf-8 -*-

# @Author : 王翔

# @WeChat : King_Uranus

# @公众号 : 清风Python

# @Date : 2019/9/22 22:11

# @Software : PyCharm

# @version :Python 3.7.3

# @File : FunnyPicture.py

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-p", "--picture", required=True,

help="请填写所需制作的图片全路径")

parser.add_argument('-t', '--type', default='join',

choices=['join', 'alone'],

help="join为分块加载,alone为轮播闪现")

parser.add_argument("-n", "--split_number", type=int, default=9,

choices=[9, 16, 25, 36, 49, 64, 81, 100],

help="选择拆分的图片数量")

args = parser.parse_args()

有了这些参数,我们就可以开始编写代码了…

图片裁剪

图片的剪裁与拆分使用什么模块呢?**from PIL import Image**简单通过Pillow的Image就可以实现相关操作了!

看到gif图我们会发现上下存在部分的留白,这是为什么?因为不是每张图都是等宽高的,所以我们要事先准备一块白色的幕布,然后将图片居中贴在白色背景图上。幕布大小如何决定,取图片宽高的最大值,生成一张正方形的白色幕布。

...

from PIL import Image

img = Image.open(args.picture.replace('\\', '/'))

_width, _height = img.size

img_size = _width if _width > _height else _height

blank_image = Image.new(self.img_mode, (self.img_size, self.img_size), color='white')

blank_image.save(....)

...

之后,就方便我们进行拆分了。

朋友圈不能发动图

我们的gif做好了,可以朋友圈不能发动图,这该如何是好?其实只需3行代码就能把一个gif的图片转化为视频文件。

模块安装:pip install moviepy

# -*- coding: utf-8 -*-

# @Author : 王翔

# @WeChat : King_Uranus

# @公众号 : 清风Python

# @Date : 2019/9/22 22:11

# @Software : PyCharm

# @version :Python 3.7.3

# @File : FunnyPicture.py

import moviepy.editor as mp

clip = mp.VideoFileClip(filename)

clip.write_videofile('result.mp4')

2019092314164479.gif

没错,就是这么简单…但该模块封装了很多子模块,总体下载还是比较大的。我们在代码中自动引入该功能,同时生成gif与MP4文件。

总体代码

总体代码如下:

# -*- coding: utf-8 -*-

# @Author : 王翔

# @WeChat : King_Uranus

# @公众号 : 清风Python

# @Date : 2019/9/22 22:11

# @Software : PyCharm

# @version :Python 3.7.3

# @File : FunnyPicture.py

import argparse

from PIL import Image

import os

import copy

import moviepy.editor as mp

BasePath = os.path.dirname(os.path.realpath(__file__))

class FunnyPicture:

def __init__(self):

self.img_mode = None

self.img_size = None

self.blank_image = None

self.git_list = list()

# 获取图片名称(去除后缀名)

self.picture_name = os.path.splitext(os.path.split(args.picture)[1])[0]

self.save_path = os.path.join(BasePath, self.picture_name)

if not os.path.exists(self.save_path):

os.mkdir(self.save_path)

# 格式化图片路径

self.picture = self.resize_picture()

def resize_picture(self):

img = Image.open(args.picture.replace('\\', '/'))

self.img_mode = img.mode

_width, _height = img.size

self.img_size = _width if _width > _height else _height

self.blank_image = Image.new(self.img_mode, (self.img_size, self.img_size), color='white')

self.blank_image.save(os.path.join(self.save_path, '{}_blank.jpg'.format(self.picture_name)))

_image = copy.copy(self.blank_image)

if _width > _height:

_image.paste(img, (0, int((self.img_size - _height) / 2)))

else:

_image.paste(img, (int((self.img_size - _width) / 2), 0))

return _image

def split_picture(self):

size = int(args.split_number ** 0.5)

side_len = int(self.img_size / size)

_index = 1

blank_image = copy.copy(self.blank_image)

for i in range(0, size):

for j in range(0, size):

if args.type != "join":

blank_image = copy.copy(self.blank_image)

per_size = (j * side_len, i * side_len, (j + 1) * side_len, (i + 1) * side_len)

per_img = self.picture.crop(per_size)

blank_image.paste(per_img, (j * side_len, i * side_len))

self.git_list.append(copy.copy(blank_image))

# 希望保留部分图片内容的可以取消注释

# 中途的每一块局部图

# per_img.save(os.path.join(self.save_path, '{}_per{}.jpg'.format(self.picture_name, _index)))

# 动图的每一帧图片

# blank_image.save(os.path.join(self.save_path, '{}_per_gif{}.jpg'.format(self.picture_name, _index)))

_index += 1

def composite_gif(self):

images = []

im = Image.open(os.path.join(self.save_path, '{}_blank.jpg'.format(self.picture_name)))

for per_gif in self.git_list:

images.append(per_gif)

for i in range(10):

images.append(self.picture)

gif_name = "{}_result.gif".format(os.path.join(self.save_path, self.picture_name))

im.save(gif_name, save_all=True, loop=True, append_images=images, duration=200)

self.composite_mp4(gif_name)

@staticmethod

def composite_mp4(filename):

clip = mp.VideoFileClip(filename)

clip.write_videofile(os.path.splitext(filename)[0] + '.mp4')

if __name__ == '__main__':

parser = argparse.ArgumentParser()

parser.add_argument("-p", "--picture", required=True,

help="请填写所需制作的图片全路径")

parser.add_argument('-t', '--type', default='join',

choices=['join', 'alone'],

help="join为分块加载,alone为轮播闪现")

parser.add_argument("-n", "--split_number", type=int, default=9,

choices=[9, 16, 25, 36, 49, 64, 81, 100],

help="选择拆分的图片数量")

args = parser.parse_args()

main = FunnyPicture()

main.split_picture()

main.composite_gif()

关于打包

既然为了好玩,当然要打包成exe的可执行文件喽。但关于打包,需要说明两点:

1.通过pyinstaller打包的软件,会被杀软误报。解压、使用时需添加白名单。

2.刚才说到moviepy依赖的模块太多,打包会导致异常,所以未将次功能进行打包,如果喜欢创建视频的,可以使用3行命令单独执行下。

来看看打包效果:

20190923141729572.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值