简体   繁体   English

如何使用 Python 图像库 (PIL) 将上传的图像保存到 FastAPI?

[英]How to save an uploaded image to FastAPI using Python Imaging Library (PIL)?

I am using image compression to reduce the image size.我正在使用图像压缩来减小图像大小。 When submitting the post request, I am not getting any error, but can't figure out why the images do not get saved.提交发布请求时,我没有收到任何错误,但无法弄清楚为什么图像没有保存。 Here is my code:这是我的代码:

@app.post("/post_ads")
async def create_upload_files(title: str = Form(),body: str = Form(), 
    db: Session = Depends(get_db), files: list[UploadFile] = File(description="Multiple files as UploadFile")):
    for file in files:
        im = Image.open(file.file)
        im = im.convert("RGB")
        im_io = BytesIO()
        im = im.save(im_io, 'JPEG', quality=50) 

PIL.Image.open() takes as fp argumnet the following: PIL.Image.open()将以下内容作为fp argumnet:

fp – A filename (string), pathlib.Path object or a file object. fpfilename (字符串)、 pathlib.Path object 或file object。 The file object must implement file.read() , file.seek() , and file.tell() methods, and be opened in binary mode.文件 object 必须实现file.read()file.seek()file.tell()方法,并以二进制模式打开。

Using a BytesIO stream, you would need to do it like this: Image.open(io.BytesIO(await file.read())) , as shown in this answer (see client side ).使用BytesIO stream,您需要这样做: Image.open(io.BytesIO(await file.read())) ,如this answer所示(见客户端)。 However, you don't really have to use an in-memory bytes buffer, as you can get the the actual file object using the .file attribute ofUploadFile .但是,您实际上不必使用内存字节缓冲区,因为您可以使用UploadFile.file属性获取实际文件 object 。 As per thedocumentation :根据文档

file : A SpooledTemporaryFile (a file-like object). file :一个SpooledTemporaryFile (一个file-like对象)。 This is the actual Python file that you can pass directly to other functions or libraries that expect a "file-like" object.这是实际的 Python 文件,您可以将其直接传递给期望“类似文件”的 object 的其他函数或库。

Example:例子:

# ...
from PIL import Image

@app.post("/upload")
def upload(file: UploadFile = File()):
    try:        
        im = Image.open(file.file)
        if im.mode in ("RGBA", "P"): 
            im = im.convert("RGB")
        im.save('out.jpg', 'JPEG', quality=50) 
    except Exception:
        # ...
    finally:
        file.file.close()
        im.close()

For more details and code examples on how to upload files/images using FastAPI, please have a look at this answer and this answer .有关如何使用 FastAPI 上传文件/图像的更多详细信息和代码示例,请查看此答案此答案 Also, please have a look at this answer for more information on defining your endpoint with def or async def .另外,请查看此答案以获取有关使用defasync def定义端点的更多信息。

I assume you are writing to a BytesIO to get an "in memory" JPEG without slowing yourself down by writing to disk and cluttering your filesystem.我假设您正在写入BytesIO以获得“内存中” JPEG,而不会因写入磁盘和弄乱文件系统而减慢自己的速度。

If so, you want:如果是这样,你想要:

im = Image.open(file.file)
im = im.convert("RGB")
im_io = BytesIO()
# create in-memory JPEG in RAM (not disk)
im.save(im_io, 'JPEG', quality=50)

# get the JPEG image in a variable called JPEG
JPEG = im_io.get_value()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM