秉持着怎么方便怎么来的原则,就用一下
Pillow
库。
1、打开图像获取尺寸,计算画布大小
Image.open
Image.size
2、创建新画布,并将目标贴进去
Image.new
Image.paste
3、对贴好图的画布进行切分
Image.crop
Image.save
界面不是很复杂,也不需要很复杂,那就用
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
from typing import Union
from PIL import Image
from os.path import exists, split as path_split
from os import makedirs
class ImgAlign:
START = 0
CENTER = 1
END = 2
MIDDLE = (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 = 1
THREELINE_MODE = 0
WHITE = '#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
@classmethod
def 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 = padding
pass
else:
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.format
width, height = im.size
width += _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 # START
if align[0] == ImgAlign.CENTER:
paste_start_x = (bk_size[0]-width)//2
elif align[0] == ImgAlign.END:
paste_start_x = bk_size[0]-width
paste_start_y = 0 # START
if align[1] == ImgAlign.CENTER:
paste_start_y = (bk_size[1]-height)//2
elif align[1] == ImgAlign.END:
paste_start_y = bk_size[1] - height
bk = Image.new('RGB', bk_size, bg)
bk.paste(im, (paste_start_x+_padding[2], paste_start_y+_padding[0]))
if save_origin:
tail = 1
origin_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 += 1
bk.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 = 1
out_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 += 1
curr_img.save(out_path)
curr_img.close()
yield i+1, out_path
bk.close()
elif mode == cls.THREELINE_MODE:
_canvas_size = max(width, height)
fix_size = 3 - _canvas_size % 3 if _canvas_size % 3 else 0
canvas_size = _canvas_size + fix_size
per_size = canvas_size // 3
paste_start_x = 0 # START
if align[0] == ImgAlign.CENTER:
paste_start_x = (canvas_size-width)//2
elif align[0] == ImgAlign.END:
paste_start_x = canvas_size-width
paste_start_y = 0 # START
if align[1] == ImgAlign.CENTER:
paste_start_y = (canvas_size-height)//2
elif align[1] == ImgAlign.END:
paste_start_y = canvas_size - height
bk = 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 = 1
origin_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 += 1
bk.save(origin_out_path)
im.close()
for row in range(3):
for col in range(3):
x_start = col * per_size
y_start = row * per_size
curr_img = bk.crop((
x_start, y_start,
x_start + per_size, y_start + per_size
))
tail = 1
out_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 += 1
curr_img.save(out_path)
curr_img.close()
yield row*3+col+1, out_path
bk.close()