import numpy as np
import PIL.Image, PIL.ImageDraw, PIL.ImageFilter, PIL.ImageFont, PIL.ImageOps
from .utilities import _color, _coord_circle
[docs]def image_circles(
width=500,
height=500,
n=100,
x=None,
y=None,
size_min=0.05,
size_max=0.2,
size=None,
color=None,
alpha=1,
blur=0,
antialias=True,
image=None,
background="white",
):
"""
Creates a PIL image of circles.
Parameters
----------
width : int
Width of the returned image.
height : int
Height of the returned image.
n : int
Number of circles drawn in the returned image.
x : Union[list, np.array, pd.Series]
x-coordinates of all circles from -1 to 1.
y : Union[list, np.array, pd.Series]
y-coordinates of all circles from -1 to 1.
size_min, size_max : int
The minimum and maximum diameter of the circles drawn. Used only if size is None.
If used, circles of random diameters from size_min to size_max are displayed.
size : int
The diameters of the circles drawn. Defaults to None.
color : str
Color of the circles returned.
alpha : int
Transparency of the circles drawn, 0 (transparent) to 1 (opaque).
blur : int
Degree of blur filter for the image returned.
antialias : bool
If true, resize the image using a high-quality downsampling filter.
image : Image
If None, an image will be created.
background : str
Color of the background.
Returns
-------
Image
Image of circle(s).
Examples
---------
>>> import pyllusion
>>>
>>> image = pyllusion.image_circles()
>>> image = pyllusion.image_circles(color="bw", blur=0.01)
>>> image = pyllusion.image_circles(n=250, size_min=0.1, size_max=0.6, alpha=0.5)
>>> image
"""
# Sanity checks
if size_max <= size_min:
size_min = size_max / 10
# Get image
if image is None:
image = PIL.Image.new("RGB", (width, height), color=background)
# Sanitize circle parameters
if x is None:
x = np.random.uniform(-1, 1, n)
if y is None:
y = np.random.uniform(-1, 1, n)
if size is None:
size = np.random.uniform(size_min, size_max, n)
else:
try:
len(size)
except TypeError:
size = [size] * n
if color is None:
color = np.random.randint(0, 256, size=(n, 3))
elif isinstance(color, str):
if color in ["bw", "blackwhite"]:
color = np.random.randint(0, 256, size=n)
else:
color = [color] * n
# Draw circle
for i in range(n):
# Draw
image = image_circle(
image=image,
x=x[i],
y=y[i],
size=size[i],
color=color[i],
alpha=alpha,
blur=blur,
antialias=antialias,
)
return image
[docs]def image_circle(
width=800,
height=600,
x=0,
y=0,
size=1,
color="black",
outline=0,
color_outline="black",
alpha=1,
blur=0,
antialias=True,
image=None,
background="white",
):
"""
Creates a PIL image of a circle.
Parameters
----------
width : int
Width of the returned image.
height : int
Height of the returned image.
x : Union[list, np.array, pd.Series]
x-coordinates of the circle from -1 to 1.
y : Union[list, np.array, pd.Series]
y-coordinates of the circle from -1 to 1.
size : int
The diameter of the circle drawn.
color : str
Color of the circle returned.
outline : float
The width of the outline of the circle.
color_outline : str
Outline of the circle outline returned.
alpha : int
Transparency of the circle drawn, 0 (transparent) to 1 (opaque).
blur : int
Degree of blur filter for the image returned.
antialias : bool
If true, resize the image using a high-quality downsampling filter.
image : Image
If None, an image will be created.
background : str
Color of the background.
Returns
-------
Image
Image of circle.
Examples
--------
>>> import pyllusion
>>>
>>> image = pyllusion.image_circle()
>>> image = pyllusion.image_circle(image=image, color="red", x=0.5, size=0.5)
>>> image = pyllusion.image_circle(image=image, color="blue", x=-0.3, size=0.5, blur=0.05)
>>> image = pyllusion.image_circle(image=image, color="yellow", y=0.5, alpha=0.5)
>>> image = pyllusion.image_circle(image=image, color="white", size=0.3, y=-0.5, outline=1)
>>> image
"""
# Get image
if image is None:
image = PIL.Image.new("RGBA", (width, height), color=background)
else:
image = image.convert("RGBA")
width, height = image.size
# Upsample
if antialias is True:
width, height = width * 3, height * 3
# Create mask
mask = PIL.Image.new("RGBA", (width, height))
draw = PIL.ImageDraw.Draw(mask)
# Circle coordinates
coord = _coord_circle(mask, diameter=size, x=x, y=y)
# Draw circle
draw.ellipse(
coord,
fill=tuple(_color(color, alpha=alpha, mode="RGBA")),
width=outline,
outline=color_outline,
)
# resize with antialiasing
if antialias is True:
mask = mask.resize(image.size, PIL.Image.ANTIALIAS)
# Blur the image a bit
if blur > 0:
mask = mask.filter(PIL.ImageFilter.GaussianBlur(blur * mask.size[1]))
# Merge and return
image = PIL.Image.alpha_composite(image, mask)
return image