用python实现千图成像工具,快给你的男/女神弄一张吧~

Python与Excel之交 2021-10-26 16:02:10
Python 工具 实现 给你 成像

千图成像也就是用N张图片组成一张图片的效果。制作方法有很多的,最常见的如用ps、懒人图云、foto-mosaik-edda这些制作。

千图成像的效果我大致分为两类:一为直接用N张图片根据底图的像素颜色、大小,一张张的组成底图,如foto-mosaik-edda;二为用N张图片根据底图的像素大小,组成一张与底图大小相仿的图片,再把二者合成,经调整透明度而成的图片,如ps。

第一种算是真正意义的千图成像,但如果选的图片不够底图的像素颜色匹配,就会造成生成的图片畸形,但如果选择的图片够好,最终的效果会非常好;第二种的效果就比较平淡了,但对选择的图片没什么要求,生成的图片比较正常。

二者的效果各有千秋,而本文使用python实现的是第二种方法,最后制成GUI。

前置

本文使用PySimpleGUI进行GUI设计,PIL、numpy、random 进行图片处理,os进行文件操作:

import PySimpleGUI as sg
from PIL import Image
import os
import numpy as np
import random

相关库使用pip命令安装即可:

pip install 库名

GUI制作

为了以后方便使用,不用一次次跑程序,而在原有的程序基础上进行GUI制作,最后打包成.exe可执行文件。

GUI界面设计

对于GUI界面的功能只需要设定五个功能即可:

  • 选择底图功能
  • 选择组图功能
  • 事件展示区域
  • 启动工具按钮
  • 退出工具按钮

最终设计代码如下:

# 主题设置
sg.theme('LightBrown3')
# 布局设置
layout = [
[sg.Frame(layout=[
[sg.InputText(key='image_file', size=(32, 1), font=("微软雅黑", 10), enable_events=True),
# 设定能选择的图片格式
sg.FileBrowse('选择底图',
file_types=(("Text Files", "*.png*"), ("Text Files", "*.jpg*"), ("Text Files", "*.jpeg*")),
font=("微软雅黑", 12)),
sg.Button('选择组图', font=("微软雅黑", 12)),
],
],
title='内容选择', title_color='blue', font=("微软雅黑", 10), relief=sg.RELIEF_SUNKEN, )],
[sg.Frame(layout=[
[sg.Output(size=(51, 10), font=("微软雅黑", 10))],
],
title='信息展示', title_color='blue', font=("微软雅黑", 10), relief=sg.RELIEF_SUNKEN, )],
[sg.Button('开始生成', font=("微软雅黑", 12)),
sg.Text('', font=("微软雅黑", 12), size=(27, 0)), sg.Button('退出程序', font=("微软雅黑", 12), button_color='red')]
]
# 创建窗口
window = sg.Window('千图成像', layout, font=("微软雅黑", 12), default_element_size=(80, 1))
while True:
# 退出按钮
event, values = window.read()
if event in (None, '退出程序'):
break
window.close()

界面效果如下:

GUI界面效果

逻辑设计

获取图片时,因为可以输入路径,可能会造成保存,所以这里加个判断;最后把得到的图片路径存入列表中。

if event == 'image_file':
files = values['image_file']
if os.path.exists(files):
img_Main_file.append(files)
else:
print('图片不存在,请重新选择图片!')
# 弹窗
sg.popup('图片不存在,请重新选择图片!')

获取组图所在的文件夹路径,依然把得到的路径存入列表中:

if event == '选择组图':
files = sg.popup_get_folder('请选择选择组图路径:')
if os.path.exists(files):
img_secondary_file.append(files)
else:
print('文件不存在,请重新选择文件')
sg.popup('文件不存在,请重新选择文件')

启动按钮,点击时把两个列表传入图片处理函数中:

if event == '开始生成':
if len(img_Main_file) and len(img_secondary_file) != 0:
img_save(img_Main_file, img_secondary_file)
else:
sg.popup('未选择!')

图片处理

因为无法保证所有图片的大小都一样,所以需要经过一定的处理。图片处理使用的库是PIL和numpy。

修改底图大小

对于底图,我们可以称之为‘容器’,底图的大小决定其组成图片的多少,也可以决定组成图片的像素大小、是否清晰。取出底图的高宽越多,图片越大,图片越清晰;取出底图百分之十的大小,这个数值可以增大,但最好不要超过百分之三十。

open_img = Image.open('./底图.jpg')
# 获取图片本身宽度、高度
width, height = open_img.size
# 重新计算底图高宽,加大底图的像素。取出底图的10%的高宽,用int进行取整
Increase_width = int(width * 0.10) * int(height * 0.10)
Increase_height = ((Increase_width / width) * height // round(height * 0.10)) * round(height * 0.10)
# 更改为重新计算的大小
open_img = open_img.resize((int(Increase_width), int(Increase_height)), Image.ANTIALIAS)

修改组图大小

把组成图片的大小修改为底图的百分之十的大小,这个数值也可以增大:

# 读取文件路径下的图片,并修改大小
img_matrix = []
for e in os.listdir('./image'):
# 防止文件夹中出现并图片格式的文件
try:
img_matrix.append(np.array(Image.open(os.path.join(str(img_files_list[0]), e)).convert('RGB').resize(
(int(width * 0.10), int(height * 0.10)), Image.ANTIALIAS)))
except OSError as e:
print(e)

计算图片填充次数

上面说过,底图的大小决定了组成图片的多少,而下面的代码就是根据底图的大小以及组成图片的大小计算出主图能填充多少图片:

# 计算主图高宽能填充多少图片
width_picture_Fill_frequency = int(Increase_width / int(width * 0.10))
height_picture_Fill_frequency = int(Increase_height / int(height * 0.10))

组图合成

根据底图高宽的10%以及图片填充次数,得出矩阵,然后把组图随机填充到矩阵中:

array_img = np.zeros_like(np.array(open_img))
for i in range(width_picture_Fill_frequency):
for x in range(height_picture_Fill_frequency):
array_img[x * int(height * 0.10):(x + 1) * int(height * 0.10),
i * int(width * 0.10):(i + 1) * int(width * 0.10), :] = random.choice(img_matrix)
array_img = Image.fromarray(array_img)

生成的图片清晰度还是很高的,不过在手机上看比较模糊:

组图效果

图片合成

把底图和组图进行合并,alpha可以调整二者的透明度,最佳为0.7、0.8、0.9。

img = Image.blend(array_img, open_img, alpha=0.8) # 0.7,0.8,0.9
img.save('千图成像.jpg')

图片效果

GUI打包

打包可以直接使用pyinstaller进行安装;如果你不知道怎么打包,或者不熟悉命令行操作,可以使用前面文章:打包工具,这款打包工具可以简单的满足打包需求。

使用pyinstaller库打包,启动命令行窗口,在命令行窗口cd到文件所在的文件目录中,最后用下面命令进行打包:

pyinstaller -F -w 名称.py

打包时可能会报错:

报错示例

报错源于一个hook-sqlalchemy.py文件,一个简单的解决方法是找到它直接回收删除它(最后暂未发现删除它对打包后的exe文件有什么影响),等打包完成后在放回去即可:

打包过程没出现什么状况,会得到几个文件,进入dist文件夹,就可以看见.exe文件了。

至此,我们就成功利用Python实现了制作千图成像工具。

本文使用的图片、代码以及生成的小工具,可以关注”Python与Excel之交“,在后台回复“千图成像”即可获取,自己操作一遍会有更好更好的效果哦!

以上便是今天的全部内容了,原创不易,欢迎点赞、分享,支持我继续写下去!

本文分享自微信公众号 - Python与Excel之交(Yi-Python-Excel) ,作者:锋小刀

原文出处及转载信息见文内详细说明,如有侵权,请联系 [email protected] 删除。

原始发表时间: 2021-10-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

版权声明
本文为[Python与Excel之交]所创,转载请带上原文链接,感谢
https://cloud.tencent.com/developer/article/1893528

  1. It's time for everyone to see your blog written in Django (including deployment tutorial video)
  2. Python扩展速记符 要求用for循环,if语句
  3. Python擴展速記符 要求用for循環,if語句
  4. Le sténographe d'extension Python nécessite une boucle pour, si instruction
  5. Python+人工智能就业班v5.0wumi
  6. python编程技术的题目,希望能得到解答
  7. Pandas determines the header row dynamically
  8. 关于#python#的问题:模拟登陆后能获取到cookie,就是cookie一天就过期
  9. pandas为dataframe添加新的数据行(rows)、在dataframe后面纵向添加一行数据(数据为列表list形式)、列有不匹配将会使用NA值进行填补
  10. pandas使用组合条件筛选、过滤数据行
  11. 热烈祝贺1024,求解Python3.10闪退问题
  12. Python基础题练习题库有没呢?
  13. python构建神经网络,正向和反向传播
  14. python爬虫输入数字翻页才成功,用变量代替不成功,为什么?
  15. 【Python 爬虫】 2、HTTP基本原理
  16. 【Python 爬虫】 1、爬虫基础概念
  17. Python中如何用find函数计数?
  18. 一文搞懂Python装饰器
  19. python数据结构之递归
  20. 关于#python#的问题:为什么这个open函数会报错
  21. Python:多输入数字求和(Python 程序控制结构)
  22. python忽略警告
  23. Python多维数组问题(编写程序统计成绩)
  24. 一步一步展示并总结Python的异常【建议收藏】
  25. Python中奇葩的round函数!
  26. 总结一下Python的模块加载解析
  27. 保姆级指导给Python库创建桌面快捷方式【赶紧收藏】
  28. 多图速成Python基础语法下篇【万字建议收藏】
  29. Python 命令行工具辅助getopt使用解析!
  30. 【python种子项目ppc】保姆级别指导给项目添加测试
  31. 【python种子项目ppc】一行代码生成项目与开发详细指导
  32. 保姆级教程带你开发优质的Python库之下篇【种子项目】
  33. 保姆级教程带你开发优质的Python库之中篇【命令行发行】
  34. 保姆级教程带你开发优质的Python库之上篇【建议收藏】
  35. python列表自动计算总分程序
  36. 某企业职工的月薪问题python 求解 不知道自己哪里写错了
  37. Python中外部函数对class类中的属性的调用
  38. 朋友股票亏惨了,我一怒用Python爬取了证券最新数据
  39. 习题8和9怎么写(Python基础)
  40. python数据分析,求任务4,5
  41. Python 的 f-strings,远比你想象的要强大!
  42. django channels channel_layer.group_send 造成内存溢出
  43. 判断天数问题用python 解决 不知道自己哪里写错了 一直显示invalid syntax
  44. OpenCV-Python对比度受限的自适应直方图均衡CLAHE知识介绍
  45. pandas 如何读取指定位置和数量的列
  46. django后台模型中的文件字段,上传后再下载时提示找不到页面
  47. 关于#python#的问题:使用requests请求网页时出现网页过期是怎么回事啊,cookie也没有过期,也提交了头文件的
  48. Pycharm开发Django项目外键和表关系
  49. [PYTHON][BAT][SHELL] 常见易忘 python、bat、shell 脚本操作汇总(持续更新)
  50. django学习-34.【多对多】表关系对应的完整业务操作
  51. 在GitHub上下载了一个python代码,看readme很疑惑,求解答
  52. 怎么用python程序做这问题
  53. python程序设计实验4-程序的异常处理
  54. 【Python每日作业】Day7: 如何在一个表达式里面合并两个字典?
  55. Python Type Hints 从入门到实践
  56. pyinstaller 打包 exe 无法在没有装python的电脑上运行,提示如下。。
  57. 关于Python中的Image. open函数的使用出现的问题
  58. 代码0基础先学哪个?WEB、python、JAVA
  59. Python基于PCANBasic二次开发使用方法
  60. Python实现相加为奇数则用户赢,如果并且用户能自行选择退出游戏,且计算他们的分数