python: 基于fastapi的图片i/o的一个问题
python: A problem of image i/o based on fastapi
尝试做一个基于fastapi的图片风格迁移代码
我参考了Github中的很多文章和stack overflow做了代码,
我发现把图片的byte转成base64传输很有效
所以,我将我的客户端代码设计成 base64 编码并发送了一个请求,
我的服务器完美接收了它。
但是,我在将图像字节恢复到 ndarray 时遇到困难。
我的代码告诉我以下错误:
image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)
ValueError: cannot reshape array of size 524288 into shape (512,512,4)
这是我的客户端代码:
import base64
import requests
import numpy as np
import json
from matplotlib.pyplot import imread
from skimage.transform import resize
if __name__ == '__main__':
path_to_img = "my image path"
image = imread(path_to_img)
image = resize(image, (512, 512))
image_byte = base64.b64encode(image.tobytes())
data = {"shape": image.shape, "image": image_byte.decode()}
response = requests.get('http://127.0.0.1:8000/myapp/v1/filter/a', data=json.dumps(data))
并且,这是我的服务器代码:
import json
import base64
import uvicorn
import model_loader
import numpy as np
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/myapp/v1/filter/a")
async def style_transfer(data: dict):
image_byte = data.get('image').encode()
image_shape = tuple(data.get('shape'))
image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)
if __name__ == '__main__':
uvicorn.run(app, port='8000', host="127.0.0.1")
请检查我的代码并给我一些建议。
我真的不知道我错过了什么。
如前所述here, here and here, one should use UploadFile
,以便从客户端应用上传文件。例如:
服务器端:
@app.post("/upload")
async def upload(file: UploadFile = File(...)):
try:
contents = await file.read()
with open(file.filename, 'wb') as f:
f.write(contents)
except Exception:
return {"message": "There was an error uploading the file"}
finally:
await file.close()
return {"message": f"Successfuly uploaded {file.filename}"}
客户端:
import requests
url = 'http://127.0.0.1:8000/upload'
file = {'file': open('images/1.png', 'rb')}
resp = requests.post(url=url, files=file)
print(resp.json())
但是,如果您仍然需要发送 base64
编码图像,您可以按照前面所述 here(选项 2)进行操作。在客户端,您可以将图像编码为 base64
并使用 POST
请求发送它,如下所示:
with open("photo.png", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
payload ={"filename": "photo.png", "filedata": encoded_string}
resp = requests.post(url=url, data=payload)
在服务器端,您可以使用 Form
字段接收图像,并按如下方式解码图像:
@app.post("/upload")
async def upload(filename: str = Form(...), filedata: str = Form(...)):
image_as_bytes = str.encode(filedata) # convert string to bytes
img_recovered = base64.b64decode(image_as_bytes) # decode base64string
try:
with open("uploaded_" + filename, "wb") as f:
f.write(img_recovered)
except Exception:
return {"message": "There was an error uploading the file"}
return {"message": f"Successfuly uploaded {filename}"}
尝试做一个基于fastapi的图片风格迁移代码
我参考了Github中的很多文章和stack overflow做了代码, 我发现把图片的byte转成base64传输很有效
所以,我将我的客户端代码设计成 base64 编码并发送了一个请求, 我的服务器完美接收了它。
但是,我在将图像字节恢复到 ndarray 时遇到困难。
我的代码告诉我以下错误:
image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)
ValueError: cannot reshape array of size 524288 into shape (512,512,4)
这是我的客户端代码:
import base64
import requests
import numpy as np
import json
from matplotlib.pyplot import imread
from skimage.transform import resize
if __name__ == '__main__':
path_to_img = "my image path"
image = imread(path_to_img)
image = resize(image, (512, 512))
image_byte = base64.b64encode(image.tobytes())
data = {"shape": image.shape, "image": image_byte.decode()}
response = requests.get('http://127.0.0.1:8000/myapp/v1/filter/a', data=json.dumps(data))
并且,这是我的服务器代码:
import json
import base64
import uvicorn
import model_loader
import numpy as np
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/myapp/v1/filter/a")
async def style_transfer(data: dict):
image_byte = data.get('image').encode()
image_shape = tuple(data.get('shape'))
image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)
if __name__ == '__main__':
uvicorn.run(app, port='8000', host="127.0.0.1")
请检查我的代码并给我一些建议。 我真的不知道我错过了什么。
如前所述here, here and here, one should use UploadFile
,以便从客户端应用上传文件。例如:
服务器端:
@app.post("/upload")
async def upload(file: UploadFile = File(...)):
try:
contents = await file.read()
with open(file.filename, 'wb') as f:
f.write(contents)
except Exception:
return {"message": "There was an error uploading the file"}
finally:
await file.close()
return {"message": f"Successfuly uploaded {file.filename}"}
客户端:
import requests
url = 'http://127.0.0.1:8000/upload'
file = {'file': open('images/1.png', 'rb')}
resp = requests.post(url=url, files=file)
print(resp.json())
但是,如果您仍然需要发送 base64
编码图像,您可以按照前面所述 here(选项 2)进行操作。在客户端,您可以将图像编码为 base64
并使用 POST
请求发送它,如下所示:
with open("photo.png", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
payload ={"filename": "photo.png", "filedata": encoded_string}
resp = requests.post(url=url, data=payload)
在服务器端,您可以使用 Form
字段接收图像,并按如下方式解码图像:
@app.post("/upload")
async def upload(filename: str = Form(...), filedata: str = Form(...)):
image_as_bytes = str.encode(filedata) # convert string to bytes
img_recovered = base64.b64decode(image_as_bytes) # decode base64string
try:
with open("uploaded_" + filename, "wb") as f:
f.write(img_recovered)
except Exception:
return {"message": "There was an error uploading the file"}
return {"message": f"Successfuly uploaded {filename}"}