Browse Source

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

master
bruegeln 3 months ago
parent
commit
9e3cf97a63
4 changed files with 106 additions and 0 deletions
  1. +10
    -0
      README.md
  2. +7
    -0
      fileutils.py
  3. +45
    -0
      img_proc.py
  4. +44
    -0
      main.py

+ 10
- 0
README.md View File

@ -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

+ 7
- 0
fileutils.py View File

@ -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

+ 45
- 0
img_proc.py View File

@ -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")

+ 44
- 0
main.py View File

@ -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…
Cancel
Save