有趣的图片

如何能让图片变得好玩?首先需要让它动起来!可如果是多张图片,我们还可以将其拼接起来组成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')

没错,就是这么简单…但该模块封装了很多子模块,总体下载还是比较大的。我们在代码中自动引入该功能,同时生成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行命令单独执行下。

来看看打包效果:

作者:清风Python

如何把图片变得炫酷多彩,Python教你这样实现!的更多相关文章

  1. Android让你的Toast变得炫酷

    一.代码: app.gradle: dependencies{ compile 'com.sdsmdg.tastytoast:tastytoast:0.0.2'} java代码: TastyToast ...

  2. 炫酷实用的jQuery插件 涵盖菜单、按钮、图片

    新的一周开始了,今天我们要为大家分享一些全新的jQuery插件和HTML5/CSS3应用,这些jQuery插件不仅非常炫酷,而且还挺实用,这次的分享包含jQuery菜单.CSS3按钮已经多种图片特效, ...

  3. 教你做炫酷的碎片式图片切换 (canvas)

    前言 老规矩,先上 DEMO 和 源码.图片区域是可以点击的,动画会从点击的位置开始发生. 本来这个效果是我3年前做的,只是当是是用无数个 div 标签完成的,性能比较成问题,在移动端完全跑不动.最近 ...

  4. 基于jQuery和CSS3炫酷图片3D旋转幻灯片特效

    在线预览   源码下载 iPresenter是一款效果非常炫酷的jQuery和CSS3 3D旋转幻灯片特效插件.你可以使用它来制作产品展示.图片画廊或者各种幻灯片和轮播图特效.这款幻灯片插件的特点有: ...

  5. 基于HTML5 SVG和CSS3炫酷蹦床式图片切换特效

    今天给大家分享一款效果非常炫酷的HTML5 SVG和CSS3蹦床式图片切换特效插件.该图片切换插件在进行图片切换时,整个屏幕就像一张大蹦床一样,将图片弹射出去,切换到另一张图片,效果非常有创意.效果图 ...

  6. 用Python一键生成炫酷九宫格图片,火了朋友圈

  7. 炫酷的CSS3抖动样式:CSS Shake

    CSS Shake是一个使用CSS3实现的动画样式,使用SASS编写,利用它我们可以实现多种不同样式的抖动效果(如下面的GIF图像): 炫酷的CSS3抖动样式:CSS Shake 这是一个很微小的动画 ...

  8. 10大炫酷的HTML5文字动画特效欣赏

    文字是网页中最基本的元素,在CSS2.0时代,我们只能在网页上展示静态的文字,只能改变他的大小和颜色,显得枯燥无味.随着HTML5的发展,现在网页中的文字样式变得越来越丰富了,甚至出现了文字动画,HT ...

  9. 简单CSS3实现炫酷读者墙

    如题,给大家介绍和讲解几个常用的CSS3属性,并用到实处. 先看demo(请使用Chrome或者Firefox浏览,IE的靠边): 点此查看实例 觉得爽的可以继续阅读下面的知识点,感觉不爽的可绕行. ...

随机推荐

  1. [考试反思]0805NOIP模拟测试13:窒息

    呼啊...苟住了.rank #3 第二次分机房的收官之战.发挥比较稳定 然而差点就不稳定了!!! 过了一遍题目,难度大约是升序,但是一道都不会做!!! 本来感觉T1是一道数学题,以为45分钟以内可以切 ...

  2. python学习之【第九篇】:Python中的变量作用域

    1.前言 Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的. 2.变量作用域 变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称.Python的作 ...

  3. Kubernetes3-kubectl管理Kubernetes容器平台-2

    一.kubectl管理集群中deployment资源与service服务 1.相关参数 kubectl edit 编辑服务器侧资源 kubectl replace 替换,使用 yaml 配置文件来替换 ...

  4. 『题解』洛谷P1993 小K的农场

    更好的阅读体验 Portal Portal1: Luogu Description 小\(K\)在\(\mathrm MC\)里面建立很多很多的农场,总共\(n\)个,以至于他自己都忘记了每个农场中种 ...

  5. 开启docker中的mongodb认证授权

    前言: 开启MongoDB服务后,默认是没有权限验证的.直接通过IP加端口就可以远程访问数据库,并对数据库进行任意操作.下面介绍一下如何开启docker中MongoDB的权限认证. 安装完MongoD ...

  6. C#同级catch块和finally块中全都抛出异常,上一级捕获哪一个?

    C#同级catch块和finally块中全都抛出异常,上一级优先捕获finally块中的异常. 测试代码: using System; namespace test { class Program { ...

  7. 如何对 React 函数式组件进行优化

    文章首发个人博客 前言 目的 本文只介绍函数式组件特有的性能优化方式,类组件和函数式组件都有的不介绍,比如 key 的使用.另外本文不详细的介绍 API 的使用,后面也许会写,其实想用好 hooks ...

  8. Maven系列第8篇:你的maven项目构建太慢了,我实在看不下去,带你一起磨刀!!多数使用maven的人都经常想要的一种功能,但是大多数人都不知道如何使用!!!

    maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能. 这是maven系列第8篇. 整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部 ...

  9. PHP字符逃逸导致的对象注入

    1.漏洞产生原因: 序列化的字符串在经过过滤函数不正确的处理而导致对象注入,目前看到都是因为过滤函数放在了serialize函数之后,要是放在序列化之前应该就不会产生这个问题 ?php functio ...

  10. 移动端自动化测试Appium环境搭建(part1-2-3)

    Appium移动端自动化测试相信大家都不陌生,appium的铁哥们是selenium,不管是selenium还是appium,都是调用webdriver来做自动化测试.今天关于appium的介绍我们不 ...