75 lines
2.4 KiB
Python
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)
|