seems to work for now. GET / will return HTML and via POST / one can upload an image and will get the pixelated result as binary stream
parent
b25a2df945
commit
9e3cf97a63
@ -0,0 +1,10 @@ |
||||
# pixelate via API |
||||
|
||||
Setup: |
||||
```bash |
||||
python3 -m venv venv |
||||
source venv/bin/activate |
||||
pip install -r requirements.txt |
||||
uvicorn main:app --reload |
||||
``` |
||||
and go to http://localhost:8000 |
@ -0,0 +1,7 @@ |
||||
from pathlib import Path |
||||
|
||||
VALID_FILE_FORMATS = [".jpg",".jpeg",".png"] |
||||
|
||||
|
||||
def has_valid_suffix(file): |
||||
return Path(file).suffix.lower() in VALID_FILE_FORMATS |
@ -0,0 +1,45 @@ |
||||
import numpy as np |
||||
from PIL import Image, ImageEnhance |
||||
import io |
||||
|
||||
def pixelate(img_name: str, |
||||
saturation: float = 1.25, |
||||
contrast: float = 1.2, |
||||
n_colors: int = 10, |
||||
superpixel_size: int = 10): |
||||
""" |
||||
See: https://github.com/ferretj/pixelate |
||||
""" |
||||
|
||||
img = Image.open(img_name) |
||||
img_size = img.size |
||||
|
||||
# boost saturation of image |
||||
sat_booster = ImageEnhance.Color(img) |
||||
img = sat_booster.enhance(saturation) |
||||
|
||||
# increase contrast of image |
||||
contr_booster = ImageEnhance.Contrast(img) |
||||
img = contr_booster.enhance(contrast) |
||||
|
||||
# reduce the number of colors used in picture |
||||
img = img.convert('P', palette=Image.ADAPTIVE, colors=n_colors) |
||||
# reduce image size |
||||
reduced_size = (img_size[0] // superpixel_size, img_size[1] // superpixel_size) |
||||
img = img.resize(reduced_size, Image.BICUBIC) |
||||
|
||||
# resize to original shape to give pixelated look |
||||
img = img.resize(img_size, Image.BICUBIC) |
||||
|
||||
return img |
||||
|
||||
|
||||
def img2byte(img:Image): |
||||
imgByteArr = io.BytesIO() |
||||
img.save(imgByteArr, format="PNG") |
||||
imgByteArr = imgByteArr.getvalue() |
||||
return imgByteArr |
||||
|
||||
if __name__ == '__main__': |
||||
img = pixelate("img.jpg") |
||||
img.save("out.png") |
@ -0,0 +1,44 @@ |
||||
from fastapi import FastAPI, File, UploadFile, Response, HTTPException |
||||
from fastapi.responses import HTMLResponse |
||||
from img_proc import pixelate, img2byte |
||||
import fileutils as fu |
||||
|
||||
app = FastAPI() |
||||
|
||||
|
||||
@app.get("/", response_class=HTMLResponse, include_in_schema=False) |
||||
async def root_html(): |
||||
return """ |
||||
<html> |
||||
<head> |
||||
<title>pixelate via API</title> |
||||
</head> |
||||
<body> |
||||
<h2>pixelate</h2> |
||||
<strong> go to <a href="/docs"> /docs</a> for OpenAPI docs </strong> |
||||
<p>based on: <a href="https://github.com/ferretj/pixelate">https://github.com/ferretj/pixelate</a> </p> |
||||
</body> |
||||
</html> |
||||
""" |
||||
|
||||
@app.post("/") |
||||
async def root(saturation: float = 1.5, |
||||
contrast: float = 1.2, |
||||
n_colors: int = 10, |
||||
superpixel_size: int = 15, |
||||
file: UploadFile = File(...)): |
||||
""" |
||||
saturation: float = 1.25, |
||||
contrast: float = 1.2, |
||||
n_colors: int = 10, |
||||
superpixel_size: int = 10, |
||||
""" |
||||
if not fu.has_valid_suffix(file.filename): |
||||
raise HTTPException(status_code=400, |
||||
detail="Invalid file ending! Only {} accepted".fomrat(fs.VALID_FILE_FORMATS)) |
||||
out_img = pixelate(file.file, |
||||
saturation = saturation, |
||||
contrast = contrast, |
||||
n_colors = n_colors, |
||||
superpixel_size = superpixel_size) |
||||
return Response(content=img2byte(out_img), media_type="image/png") |
Loading…
Reference in new issue