鱼C论坛

 找回密码
 立即注册
查看: 12029|回复: 48

[技术交流] 做一个炫酷朋友圈的九宫格图吧!

[复制链接]
发表于 2020-5-27 16:22:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 不二如是 于 2020-10-27 11:35 编辑



前几日逛吹水阁,看完潘石屹大佬通过 Python 考试的帖子(传送门),被里面的 Tag 触动了:

                               
登录/注册后可看大图


对吼,如果 Python 不能用来搞事情,将失去多少乐趣!

今天小师妹就再教大家一招!

都看过朋友圈(其他社交平台同理)这样的 9 宫格图吧:
Snip20200527_25.png
(PS:代码不会的不加好友


用软件可以实现,但作为程序员,肯定要写代码咯。

先简单梳理下思路:

  • 读取初始照片
  • 比较照片的宽高,数值较大的作为边长生成以白色为背景的大正方形图
  • 将大正方形图进行切割,按照 3*3 比列,变成 9 个小图
  • 保存小图

基本思路有了,那就开始敲代码吧。

这个小功能的实现利用了 Python 中的一个图形处理库:Pillow 。

Snip20200529_53.png
官网:传送门


Pillow 是从著名的 Python 图像处理库 PIL 发展出来的一个分支。

通过 Pillow 可以实现图像压缩图像处理等操作。

安装很简单,师兄们自己来吧。

思路就按照上面的来,


1、读取照片

先来引入库,并获取当前文件所在文件夹:

  1. from PIL import Image
  2. import os

  3. __author__ = '鱼C-小师妹'

  4. #当前文件所在文件夹
  5. DIR_NAME = os.path.dirname( os.path.abspath(__file__) )
复制代码

老规矩当模块直接被运行的时候,执行一个我们自己封装的函数:

  1. from PIL import Image
  2. import os

  3. __author__ = '鱼C-小师妹'

  4. #当前文件所在文件夹
  5. DIR_NAME = os.path.dirname( os.path.abspath(__file__) )

  6. if __name__ == '__main__':
  7.     fishcRun()  
复制代码

在 fishcRun() 中我们来读取本地图片:

  1. from PIL import Image
  2. import os

  3. __author__ = '鱼C-小师妹'

  4. #当前文件所在文件夹
  5. DIR_NAME = os.path.dirname( os.path.abspath(__file__) )

  6. def fishcRun():
  7.     # 读取本地文件
  8.     file_path = os.path.join(DIR_NAME, 'demo.jpg')
  9.     image = Image.open(file_path)
  10.     print('程序结束啦!')

  11. if __name__ == '__main__':
  12.     fishcRun()
复制代码

好啦,图片就读取到了。

简单测试下,启动脚本,看到控制台输出:
Snip20200529_54.png


证明现有程序没问题啦,继续下一步。


2、填充原图形的背景,生成大正方形图

这个很好理解,如果是标准正方形,宽高一样,我们直接 3 等分即可。

如果宽高不等呢?

我们就给它加个白色背景,这样切出来,发出去也看不出来大小不等。

宽高不等就又可以分成两种情况:宽大于高,高大于宽。

如果是宽大与高,就按照宽的尺寸,设置高,多出来的部分,加填充白色背景。

反之如果高大于宽,就按照高的尺寸,设置宽,多出来的部分,加填充白色背景。

分析的很清楚啦,动手写成代码吧。

先在 fishcRun() 中创建一个代表填充的 fill_images(image)。

然后按照上面流程写代码:

  1. from PIL import Image
  2. import os

  3. __author__ = '鱼C-小师妹'

  4. #当前文件所在文件夹
  5. DIR_NAME = os.path.dirname( os.path.abspath(__file__) )

  6. def fill_images(image):
  7.     """ 填充正方形白色背景图片 """
  8.     width, height = image.size  # 获取图片的宽高
  9.     side = max(width, height)  # 对比宽和高哪个大

  10.     # 新生成的图片是正方形的,边长取大的,背景设置白色
  11.     new_image = Image.new(image.mode, (side, side), color='white')

  12.     # 根据尺寸不同,将原图片放入新建的空白图片中部
  13.     if width > height:
  14.         new_image.paste(image, (0, int((side - height) / 2)))
  15.     else:
  16.         new_image.paste(image, (int((side - width) / 2), 0))
  17.     return new_image

  18. def fishcRun():
  19.      # 读取本地文件
  20.     file_path = os.path.join(DIR_NAME, 'demo.jpg')
  21.     image = Image.open(file_path)
  22.     # 填充
  23.     image = fill_images(image)

  24.     print('程序结束啦!')

  25. if __name__ == '__main__':
  26.     fishcRun()  
复制代码

好啦,注释的很清楚啦,自己看。


3、切割图

执行完 fill_images() 就有了一张正方形图。

切割不难,按照宽或者高(反正都一样)除以 3 取整即可。

然后保存每一个切出来的图。

创建 cut_images(image) 代表切图,实现如下:

  1. from PIL import Image
  2. import os

  3. __author__ = '鱼C-小师妹'

  4. #当前文件所在文件夹
  5. DIR_NAME = os.path.dirname( os.path.abspath(__file__) )

  6. def fill_images(image):
  7.     """ 填充正方形白色背景图片 """
  8.     width, height = image.size  # 获取图片的宽高
  9.     side = max(width, height)  # 对比宽和高哪个大

  10.     # 新生成的图片是正方形的,边长取大的,背景设置白色
  11.     new_image = Image.new(image.mode, (side, side), color='white')

  12.     # 根据尺寸不同,将原图片放入新建的空白图片中部
  13.     if width > height:
  14.         new_image.paste(image, (0, int((side - height) / 2)))
  15.     else:
  16.         new_image.paste(image, (int((side - width) / 2), 0))
  17.     return new_image


  18. def cut_images(image):
  19.     """ 切割原图 """
  20.     width, height = image.size
  21.     one_third_width = int(width / 3)  # 三分之一正方形线像素

  22.     # 保存每一个小切图的区域
  23.     box_list = []

  24.     """
  25.     切图区域是矩形,位置由对角线的两个点(左上,右下)确定,
  26.     而 crop() 实际要传入四个参数(left, upper, right, lower)
  27.     """
  28.     for x in range(3):
  29.         for y in range(3):
  30.             left = x * one_third_width  # 左像素
  31.             upper = y * one_third_width  # 上像素
  32.             right = (x + 1) * one_third_width  # 右像素
  33.             lower = (y + 1) * one_third_width  # 下像素
  34.             box = (left, upper, right, lower)
  35.             box_list.append(box)

  36.     image_list = [image.crop(box) for box in box_list]
  37.     return image_list

  38. def fishcRun():
  39.     # 读取本地文件
  40.     file_path = os.path.join(DIR_NAME, 'demo.jpg')
  41.     image = Image.open(file_path)
  42.     # 填充
  43.     image = fill_images(image)
  44.     # 切图
  45.     image_list = cut_images(image)

  46.     print('程序结束啦!')

  47. if __name__ == '__main__':
  48.     fishcRun()  
复制代码

切都切好了,剩下就是把图保存出来了。


4、保存切割图

我们最终要的是 9 张切割图,上面搞定定后,写个 save_images(image_list) 来保存成果:

游客,如果您要查看本帖隐藏内容请回复


保存,测试一下,跑完后,如果你看到:

Snip20200529_56.png


恭喜成功,为了让你们自己写,源码收费高一些(劝退): 源码.zip (388.93 KB, 下载次数: 48, 售价: 50 鱼币)

评分

参与人数 9荣誉 +28 鱼币 +17 贡献 +12 收起 理由
ln311 + 1 + 1 感谢楼主无私奉献!
逃兵 + 5
yankey + 5 -1 + 3
叶樱枫 + 1 + 1 鱼C有你更精彩^_^
nizitao + 3 鱼C有你更精彩^_^
_2_ + 5
不二如是 + 5 + 3 + 3 鱼C有你更精彩^_^
qiuyouzhi + 5 + 5 + 3
KevinHu + 3 + 3 + 3 先评一下

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-5-27 16:27:04 | 显示全部楼层
过二十指的是什么?鱼币?荣誉?还是贡献
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 16:31:09 | 显示全部楼层
KevinHu 发表于 2020-5-27 16:27
过二十指的是什么?鱼币?荣誉?还是贡献

20个人(
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 16:33:03 | 显示全部楼层

这个求评分的策略太高级了……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 16:54:02 | 显示全部楼层
前排支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 17:07:29 | 显示全部楼层
KevinHu 发表于 2020-5-27 16:27
过二十指的是什么?鱼币?荣誉?还是贡献

不是写了荣誉?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 17:07:57 | 显示全部楼层

刚才好像没写
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 17:08:34 | 显示全部楼层

唉是不是不二你改的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 19:54:27 From FishC Mobile | 显示全部楼层
老八秘制 发表于 2020-5-27 16:31
20个人(

不就要荣誉嘛,
给点电脑又不会崩溃
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-29 18:07:12 | 显示全部楼层
_2_ 发表于 2020-5-27 19:54
不就要荣誉嘛,
给点电脑又不会崩溃

对滴
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-31 14:48:54 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-5-31 17:37:38 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-5-31 21:02:38 | 显示全部楼层
666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-7 10:08:50 | 显示全部楼层
代码学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-7 17:23:17 | 显示全部楼层
666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-8 12:42:44 | 显示全部楼层
源码不是已经在上面了吗?怎么还要弄福附件
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-8 15:31:37 | 显示全部楼层
小师妹好厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-9 15:53:57 | 显示全部楼层
支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-10 17:49:57 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-10 17:59:26 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 04:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表