图像九宫格切分1x3、3x3 Python

文章目录

  • 1、需求
  • 2、实现
    • 2-1 贴图、切分
    • 2-2 GUI
  • 3、运行效果
  • 4、代码


1、需求

  • 把一个图像切分成 1x3 或者 3x3
  • 切分出来的图像比例希望都是 1:1 正方形
  • 如果图像尺寸满足 切分条件,自动填充一些“白边”然后继续切分
  • 如果填充了白边的话,希望能够调整原图像在画布上的位置(居中、对齐左边等)
  • 都到这了,或许可以给原图像再加一个边距,这样如果刚好够切分图像整体也会多一层“白边”

2、实现

2-1 贴图、切分

秉持着怎么方便怎么来的原则,就用一下 Pillow 库。

1、打开图像获取尺寸,计算画布大小
Image.open Image.size
2、创建新画布,并将目标贴进去
Image.new Image.paste
3、对贴好图的画布进行切分
Image.crop Image.save

2-2 GUI

界面不是很复杂,也不需要很复杂,那就用 tkinter

1、图片路径、输出路径
tkinter.filedialog tkinter.Label tkinter.Entry tkinter.Button
2、切分模式、对齐模式
tkinter.Label tkinter.Button
3、背景颜色
tkinter.Label tkinter.colorchooser.askcolor tkinter.Button
4、内边距
tkinter.Label tkinter.Scale

3、运行效果

分析结束,走你
在这里插入图片描述
3x3切分
1x3切分

4、代码

from typing import Union
from PIL import Image
from os.path import exists, split as path_split
from os import makedirsclass ImgAlign:START = 0CENTER = 1END = 2MIDDLE = (CENTER, CENTER)LEFT_CENTER = (START, CENTER)RIGHT_CENTER = (END, CENTER)LEFT_TOP = (START, START)CENTER_TOP = (CENTER, START)RIGHT_TOP = (END, START)LEFT_BOTTOM = (START, END)CENTER_BOTTOM = (CENTER, END)RIGHT_BOTTOM = (END, END)ALIGNS = [LEFT_TOP, CENTER_TOP, RIGHT_TOP,LEFT_CENTER, MIDDLE, RIGHT_CENTER,LEFT_BOTTOM, CENTER_BOTTOM, RIGHT_BOTTOM]def __getitem__(self, item: int):return self.ALIGNS[item]class ImgSpliter:ONELINE_MODE = 1THREELINE_MODE = 0WHITE = '#FFF'BLACK = '#000'PADDING = Union[int,list[int, int], tuple[int, int],list[int, int, int, int], tuple[int, int, int, int]]def __init__(self):self.id = 0@classmethoddef split_it(cls, img_path: str, out_dir='./', save_origin=False, mode=ONELINE_MODE,bg=WHITE, padding: PADDING = (0, 0), align=ImgAlign.MIDDLE):"""切分图像:param img_path: 图像路径:param out_dir: 切分后图像保存文件夹:param mode: 切分模式:一行还是三行:param bg: 画布背景颜色。Image.new 里的color配置:param padding: 画布内边距(相当于原图像外边距)。可以是 n(上下左右都是n);(上下,左右) ;(上,下,下,左,右):param align: 对齐方式。 ImgAlign 里的”枚举“:return:"""_padding = (0, 0, 0, 0)if isinstance(padding, int):_padding = (padding, padding, padding, padding)elif isinstance(padding, (tuple, list)):if len(padding) == 2:_padding = (padding[0], padding[0], padding[1], padding[1])elif len(padding) == 4:_padding = paddingpasselse:raise ValueError("padding 数组长度应为2或者4")else:raise ValueError("padding 数组长度应为2或者4")im = Image.open(img_path)img_name = '.'.join(path_split(img_path)[-1].split('.')[:-1])_out_dir = out_dir + f'/{img_name}'img_format = im.formatwidth, height = im.sizewidth += _padding[2] + _padding[3]height += _padding[0] + _padding[1]if not exists(_out_dir):makedirs(_out_dir)if mode == cls.ONELINE_MODE:# 1、宽小于等于三倍高。总长三倍高if width <= height*3:bk_size = (height*3, height)# 2、宽大于三倍高。总长等于宽,总高等于三分之一长。else:fix_width = width % 3_width = width + (3-fix_width if fix_width else 0)bk_size = (_width, _width // 3)paste_start_x = 0  # STARTif align[0] == ImgAlign.CENTER:paste_start_x = (bk_size[0]-width)//2elif align[0] == ImgAlign.END:paste_start_x = bk_size[0]-widthpaste_start_y = 0  # STARTif align[1] == ImgAlign.CENTER:paste_start_y = (bk_size[1]-height)//2elif align[1] == ImgAlign.END:paste_start_y = bk_size[1] - heightbk = Image.new('RGB', bk_size, bg)bk.paste(im, (paste_start_x+_padding[2], paste_start_y+_padding[0]))if save_origin:tail = 1origin_out_path = f'{_out_dir}/{img_name}_wrap.{img_format}'while exists(origin_out_path):origin_out_path = f'{_out_dir}/{img_name}_wrap-{tail}.{img_format}'tail += 1bk.save(origin_out_path)im.close()for i in range(3):curr_img = bk.crop((i*bk_size[1],0,(i+1) * bk_size[1],bk_size[1]))tail = 1out_path = f'{_out_dir}/{img_name}_{i+1}.{img_format}'while exists(out_path):out_path = f'{_out_dir}/{img_name}_{i+1}-{tail}.{img_format}'tail += 1curr_img.save(out_path)curr_img.close()yield i+1, out_pathbk.close()elif mode == cls.THREELINE_MODE:_canvas_size = max(width, height)fix_size = 3 - _canvas_size % 3 if _canvas_size % 3 else 0canvas_size = _canvas_size + fix_sizeper_size = canvas_size // 3paste_start_x = 0  # STARTif align[0] == ImgAlign.CENTER:paste_start_x = (canvas_size-width)//2elif align[0] == ImgAlign.END:paste_start_x = canvas_size-widthpaste_start_y = 0  # STARTif align[1] == ImgAlign.CENTER:paste_start_y = (canvas_size-height)//2elif align[1] == ImgAlign.END:paste_start_y = canvas_size - heightbk = Image.new('RGB', (canvas_size, canvas_size), bg)bk.paste(im, (paste_start_x+_padding[2], paste_start_y+_padding[0]))if save_origin:tail = 1origin_out_path = f'{_out_dir}/{img_name}_wrap.{img_format}'while exists(origin_out_path):origin_out_path = f'{_out_dir}/{img_name}_wrap-{tail}.{img_format}'tail += 1bk.save(origin_out_path)im.close()for row in range(3):for col in range(3):x_start = col * per_sizey_start = row * per_sizecurr_img = bk.crop((x_start, y_start,x_start + per_size, y_start + per_size))tail = 1out_path = f'{_out_dir}/{img_name}_{row + 1}{col + 1}.{img_format}'while exists(out_path):out_path = f'{_out_dir}/{img_name}_{row + 1}{col + 1}-{tail}.{img_format}'tail += 1curr_img.save(out_path)curr_img.close()yield row*3+col+1, out_pathbk.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/299978.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 语言实战:掌握正则表达式的应用与技巧

Go 语言实战&#xff1a;掌握正则表达式的应用与技巧 1. 引言2. 正则表达式基础2.1 基本概念2.2 常见元素2.3 基本示例 3. Go语言中的正则表达式库3.1 引入regexp包3.2 编译正则表达式3.3 使用正则表达式3.4 示例代码 4. 常用正则表达式函数及使用示例4.1 MatchString4.2 FindS…

数据库01_增删改查

1、什么是数据&#xff1f;什么是数据库&#xff1f; 数据&#xff1a;描述事物的符号记录称为数据。数据是数据库中存储的基本对象。数据库&#xff1a;存放数据的仓库&#xff0c;数据库中可以保存文本型数据、二进制数据、多媒体数据等数据 2、数据库的发展 第一阶段&…

Fireblock:为Dapp实现可编程隐私

1. 引言 Fireblock network为Cosmos生态应用链。并于2023年10月宣布完成pre-seed轮250万美金融资。 其定位为实现&#xff1a; 有条件解密可编程隐私 Fireblock使用的密码学方案有&#xff1a; distributed key generation&#xff08;DKG&#xff09;Identity-based encry…

数据库开发之多表查询的详细解析

1. 多表查询 1.1 概述 1.1.1 数据准备 SQL脚本&#xff1a; #建议&#xff1a;创建新的数据库 create database db04; use db04; ​ -- 部门表 create table tb_dept (id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not nu…

前端测试——端对端测试框架 Playwright 总结

在进行前端测试前&#xff0c;我们需要明确我们需要怎样的前端测试。 前端测试类型总结 前端应用测试分为几种常见类型: 端到端&#xff08;e2e&#xff09; &#xff1a;一个辅助机器人&#xff0c;表现得像一个用户&#xff0c;在应用程序周围点击&#xff0c;并验证其功能…

通过three.js玩转车展项目

1.项目搭建 1.1 创建文件夹 mkdir 文件名1.2 初始化package.json npm init -y1.3 安装打包工具并配置相关依赖 npm i parcel -d在package.json中打包路径和指令 1.4 安装three.js npm i three -d2.项目搭建 2.1 新建index.html&#xff0c;并再index.html引入car.js,在…

【C#】Visual Studio 2022 远程调试配置教程

在某些特殊的情况下&#xff0c;开发机和调试机可能不是同一台设备&#xff0c;此时就需要远程调试了。 开发机配置 首先需要确保两台机器在同一局域网下。 创建共享文件夹 随便找个地方新建一个文件夹&#xff0c;用来放编译结果。例如我这里是 D:\DebuggingWorkspace\。 …

正式官宣!谈思AutoSec 8周年年会暨中国汽车网络安全及数据安全合规峰会将于明年4月在沪召开

随着智能互联网时代的到来&#xff0c;智能汽车的安全形势变得更加严峻和复杂&#xff0c;网络资产的暴露和安全边界继续扩大。与传统的汽车车身安全问题相比&#xff0c;网络安全、数据安全、用户隐私等安全问题交织叠加&#xff0c;并加速了黑客对智能汽车领域的渗透&#xf…

歌曲春节回家:歌手荆涛探寻家庭与归属感的深刻内涵

歌曲春节回家&#xff1a;歌手荆涛探寻家庭与归属感的深刻内涵 春节&#xff0c;对于中国人来说&#xff0c;是一个意义非凡的节日。它不仅仅是一个传统的庆祝活动&#xff0c;更是一种深深的家庭情怀和归属感的体现。荆涛的《春节回家》这首歌&#xff0c;以其深情的旋律和富…

智能优化算法应用:基于斑马算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于斑马算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于斑马算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.斑马算法4.实验参数设定5.算法结果6.参考文献7.MA…

【数据结构入门精讲 | 第五篇】栈知识点及考研408、企业面试练习

在上一篇中我们进行了表的专项练习&#xff0c;在这篇文章中我们将介绍栈的相关知识点。 目录 基础概念顺序栈链栈判断题选择题填空题函数题R6-1 在一个数组中实现两个堆栈 编程题R7-1 汉诺塔的非递归实现R7-2 表达式转换R7-3 出栈序列的合法性R7-4 包装机R7-1 彩虹瓶 基础概念…

智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.指数分布算法4.实验参数设定5.算法结果6.…