132 lines
4.0 KiB
Python
Executable File
132 lines
4.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- encoding: utf-8 -*-
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Tuple, List
|
|
|
|
from PIL import Image, ImageDraw
|
|
|
|
|
|
START = -(sys.maxsize // 2) + 0
|
|
END = -(sys.maxsize // 2) + 1
|
|
CENTER = -(sys.maxsize // 2) + 2
|
|
|
|
POS_TOP_LEFT = (START, START)
|
|
POS_CENTER_LEFT = (START, CENTER)
|
|
POS_BOTTOM_LEFT = (START, END)
|
|
|
|
POS_TOP_CENTER = (CENTER, START)
|
|
POS_CENTER_CENTER = (CENTER, CENTER)
|
|
POS_BOTTOM_CENTER = (CENTER, END)
|
|
|
|
POS_TOP_RIGHT = (END, START)
|
|
POS_CENTER_RIGHT = (END, CENTER)
|
|
POS_BOTTOM_RIGHT = (END, END)
|
|
|
|
P_TL = POS_TOP_LEFT
|
|
P_CL = POS_CENTER_LEFT
|
|
P_BL = POS_BOTTOM_LEFT
|
|
|
|
P_TC = POS_TOP_CENTER
|
|
P_CC = POS_CENTER_CENTER
|
|
P_BC = POS_BOTTOM_CENTER
|
|
|
|
P_TR = POS_TOP_RIGHT
|
|
P_CR = POS_CENTER_RIGHT
|
|
P_BR = POS_BOTTOM_RIGHT
|
|
|
|
|
|
def edge_propagation_scaling(image: Image.Image,
|
|
desired_size: Tuple[int, int],
|
|
paste_position: Tuple[int, int] = P_CC,
|
|
) -> Image.Image:
|
|
image = image.copy()
|
|
scaled = Image.new(image.mode, desired_size)
|
|
new_placement_: List[int] = list()
|
|
for isz, ssz, pp in zip(image.size, scaled.size, paste_position,):
|
|
if pp == START:
|
|
new_placement_.append(0)
|
|
elif pp == END:
|
|
new_placement_.append(ssz-isz)
|
|
elif pp == CENTER:
|
|
new_placement_.append((ssz-isz)//2)
|
|
else:
|
|
new_placement_.append(pp)
|
|
new_placement: Tuple[int, int] = new_placement_[0], new_placement_[1]
|
|
del new_placement_
|
|
scaled.paste(image, new_placement)
|
|
parts = dict(
|
|
# left, upper, right, lower
|
|
t=image.copy().crop(
|
|
(0, 0, image.size[0], 1)),
|
|
b=image.copy().crop(
|
|
(0, image.size[1]-1, image.size[0], image.size[1])),
|
|
l=image.copy().crop(
|
|
(0, 0, 1, image.size[1])),
|
|
r=image.copy().crop(
|
|
(image.size[0]-1, 0, image.size[0], image.size[1])),
|
|
)
|
|
if (sz := new_placement[1]) > 0:
|
|
part = parts['t'].copy()
|
|
resized = part.resize((part.size[0], sz))
|
|
scaled.paste(resized, (new_placement[0], 0))
|
|
if (sz := scaled.size[1]-(dsp := new_placement[1]+image.size[1])) > 0:
|
|
part = parts['b'].copy()
|
|
resized = part.resize((part.size[0], sz))
|
|
scaled.paste(resized, (new_placement[0], dsp))
|
|
if (sz := new_placement[0]) > 0:
|
|
part = parts['l'].copy()
|
|
resized = part.resize((sz, part.size[1]))
|
|
scaled.paste(resized, (0, new_placement[1]))
|
|
if (sz := scaled.size[0]-(dsp := new_placement[0]+image.size[0])) > 0:
|
|
part = parts['r'].copy()
|
|
resized = part.resize((sz, part.size[1]))
|
|
scaled.paste(resized, (dsp, new_placement[1]))
|
|
del parts
|
|
corners = dict(
|
|
tl=image.getpixel((0, 0)),
|
|
tr=image.getpixel((image.size[0]-1, 0)),
|
|
bl=image.getpixel((0, image.size[1]-1)),
|
|
br=image.getpixel((image.size[0]-1, image.size[1]-1)),
|
|
)
|
|
draw: ImageDraw.ImageDraw = ImageDraw.Draw(scaled)
|
|
szt = new_placement[1]
|
|
szb = scaled.size[1]-(dspb := new_placement[1]+image.size[1])
|
|
szl = new_placement[0]
|
|
szr = scaled.size[0]-(dspr := new_placement[0]+image.size[0])
|
|
if szt > 0 and szl > 0:
|
|
draw.rectangle(((0, 0), (szl-1, szt-1)), corners['tl'])
|
|
if szt > 0 and szr > 0:
|
|
draw.rectangle(((dspr, 0), (scaled.size[0], szt-1)), corners['tr'])
|
|
if szb > 0 and szl > 0:
|
|
draw.rectangle(((0, dspb), (szl-1, scaled.size[1])), corners['bl'])
|
|
if szb > 0 and szr > 0:
|
|
draw.rectangle(((dspr, dspb), scaled.size), corners['br'])
|
|
del dspr
|
|
del dspb
|
|
del szt
|
|
del szb
|
|
del szl
|
|
del szr
|
|
return scaled
|
|
|
|
|
|
def main(path: Path = Path('eps_test.png')):
|
|
im: Image.Image = Image.open(path)
|
|
|
|
ptd = dict(a=START, b=CENTER, c=END)
|
|
|
|
for xp in 'abc':
|
|
for yp in 'abc':
|
|
im2 = edge_propagation_scaling(
|
|
im,
|
|
tuple(map(lambda i: int(i*2.5), im.size)),
|
|
(ptd[xp], ptd[yp]),
|
|
)
|
|
im2.save(Path(f'{path.stem}_out_{yp}{xp}{path.suffix}'))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|