FastAPIを使って、画像をアップロードして、OpenCVで変換とかして、返却するというのをやりたかったのだが、イマイチな部分もある気はするけど、メモがてらに残しておく。一応、アップロードされたファイルは一旦、一時ファイルに保存している(保存しなくても良いかもしれないけど…)。そんで、process(img)の中で、画像のimgのnumpy arrayを何か変換して、戻した画像のimg_convertedのnumpy arrayを作る。あとは、img_convertedはオンメモリでcv2.imencodeで、png形式にして、Responseで返せば、画像がダウンロードされる。画像はマルチパートでアップロードする感じだけど、FastAPIのhttp://localhost:8000/docs/で送り方を確認すればよいはず。
from fastapi import FastAPI, UploadFile, File, HTTPException, Response
import cv2
import shutil
from pathlib import Path
from tempfile import NamedTemporaryFile
app = FastAPI()
@app.post("/convert/")
def convert(file: UploadFile = File(...)):
filepath = save_upload_file_tmp(file)
try:
img = cv2.imread(str(filepath))
img_converted = process(img) # OpenCVの変換処理とか
_, img_enc = cv2.imencode('.png', img_converted)
return Response(content=img_enc.tostring(), media_type='image/png')
except Exception as e:
raise HTTPException(status_code=500, detail='Failed to convert an image.')
finally:
filepath.unlink()
def save_upload_file_tmp(upload_file: UploadFile) -> Path:
try:
suffix = Path(upload_file.filename).suffix
with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
shutil.copyfileobj(upload_file.file, tmp)
tmp_path = Path(tmp.name)
finally:
upload_file.file.close()
return tmp_path
FastAPIでアップロードされたファイルの保存はこれを参考にした。