mappersons/mappersons.py
2023-05-18 14:43:03 +02:00

75 lines
2.4 KiB
Python

import math
from PIL import Image, ImageDraw, ImageFilter
from pathlib import Path
import numpy as np
import math
def circular_mask(img):
center_x = int(img.width / 2)
center_y = int(img.height / 2)
mask = Image.new('L', img.size, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((2, 2 ,img.width-3,img.height-3),fill=255)
img.putalpha(mask.filter(ImageFilter.GaussianBlur(radius=1)))
return img
def arrange_imager_in_circle(images, spacing=5):
d = images[0].size[0]
dis = d + spacing
theta = 2*math.pi / len(images)
radius = dis/2/math.sin(theta/2)
imgWidth, imgHeight = (int(d+radius*2), int(d+radius*2))
masterImage = Image.new("RGBA", (imgWidth, imgHeight), (255,255,255,0))
#we want the circle to be as large as possible.
#but the circle shouldn't extend all the way to the edge of the image.
#If we do that, then when we paste images onto the circle, those images will partially fall over the edge.
#so we reduce the diameter of the circle by the width/height of the widest/tallest image.
circleCenterX = imgWidth / 2
circleCenterY = imgHeight / 2
for i, curImg in enumerate(images):
angle = i * theta
dx = int(radius * math.cos(angle))
dy = int(radius * math.sin(angle))
#dx and dy give the coordinates of where the center of our images would go.
#so we must subtract half the height/width of the image to find where their top-left corners should be.
pos = (
int(circleCenterX + dx - curImg.size[0]/2),
int(circleCenterY + dy - curImg.size[1]/2)
)
curMask = curImg.split()[-1]
masterImage.paste(curImg, pos, curMask)
return masterImage
def create_circle(image_paths, output_path):
# Resize all images to 64x64 pixels
shrunk_images = [Image.open(path).resize((64, 64)) for path in image_paths]
# Cut out a circle from each image
circular_images = [circular_mask(img) for img in shrunk_images]
circular_images[-1].save('circle.png')
if len(circular_images) == 1:
circular_images[0].save(output_path)
return
output_img = arrange_imager_in_circle(circular_images)
output_path = output_img.save(output_path)
if __name__ == "__main__":
p = Path("test_images")
image_paths = [str(x) for x in p.glob("*.jpg")]*2
for i in range(len(image_paths)):
output_path = "test%i.png" % i
create_circle(image_paths[:i+1], output_path)