speckles/main.py

112 lines
2.8 KiB
Python
Raw Normal View History

2023-06-14 09:05:25 +00:00
import io
2023-07-10 07:14:05 +00:00
import logging
2023-06-14 09:05:25 +00:00
import itertools
import json
import random
from collections import Counter
from copy import deepcopy
from datetime import datetime
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import uvicorn
from fastapi import FastAPI, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
app = FastAPI(title="Speckles API", root_path="/images")
origins = [
"http://localhost",
"http://localhost:3000",
"https://localhost",
"https://0124816.xyz",
"http://0124816.xyz:3001",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
MEDIA_TYPES = {
"png": "image/png",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"svg": "image/svg+xml",
"pdf": "application/pdf",
}
@app.get("/speckles/")
def make_wallpaper(
speckle_colours: str,
density: float | None = 0.12,
2023-07-10 07:14:05 +00:00
size: float | None = 3,
2023-06-14 09:05:25 +00:00
fileformat: str = "svg",
2023-07-10 07:14:05 +00:00
orientation: str | None = "landscape",
2023-06-14 09:05:25 +00:00
):
if not fileformat in MEDIA_TYPES:
return
speckle_colours = speckle_colours.split(",")
background = speckle_colours.pop(0)
2023-07-10 07:14:05 +00:00
if orientation == "portrait":
x, y = (1080, 1920)
elif orientation == "landscape":
x, y = (1920, 1080)
elif "x" in orientation:
resolution = orientation.split("x")
if len(resolution) !=2 :
logging.critical("input resolution has more or less than 2 dimensions")
return
x,y = resolution
if all([x.isdigit(), y.isdigit()]):
x,y = int(x), int(y)
else:
return
else:
x, y = (1920, 1080)
speckles_per_colour = int(x / 128 * y / 128 * density)
2023-06-14 09:05:25 +00:00
2023-07-10 07:14:05 +00:00
fig, ax = plt.subplots(figsize=(x / 120, y / 120), facecolor=background)
2023-06-14 09:05:25 +00:00
ax.set_facecolor(background)
[spine.set_color(background) for spine in ax.spines.values()]
ax.set_xticks([])
ax.set_yticks([])
ax.margins(0, 0)
for color, size in itertools.product(
speckle_colours,
2023-07-10 07:14:05 +00:00
np.logspace(0, size, 10, base=np.exp(2)),
2023-06-14 09:05:25 +00:00
):
ax.scatter(
[random.random() * x / 8 for _ in range(speckles_per_colour)],
[random.random() * y / 8 for _ in range(speckles_per_colour)],
c=color,
s=size,
)
fig.tight_layout()
# plt.xlim(0, x)
# plt.ylim(0, y)
# plt.axis("off")
buf = io.BytesIO()
fig.savefig(
buf,
format=fileformat,
dpi=128,
bbox_inches="tight",
pad_inches=0,
)
buf.seek(0)
return StreamingResponse(content=buf, media_type=MEDIA_TYPES[fileformat])
buf.close()
if __name__ == "__main__":
uvicorn.run("main:app", workers=2, port=8099, reload=False)