我正在尝试将Gradio应用转换为Flask API。在Gradio应用中,使用了诸如Image、Text等组件。我需要将这些组件转换为请求表单数据。然而,我在处理图像时遇到了困难。我需要一些帮助。
这是我的代码。cloth_image = gr.Image(label="Your label...", type="pil") cloth_mask_image = gr.Image(label="Your label...", type="pil")
如何通过预处理cloth_image = request.files['cloth_image']
来获得与gr.Image组件相同的返回值?
回答:
如果您只需要在服务器上使用图像(作为PIL
),那么您可以直接使用
from PIL import Imagecloth_image = Image.open( request.files["cloth_image"] )
因为files["cloth_image"]
有.read()
方法,所以它可以被视为文件对象,而Image.open()
可以使用文件对象而不是文件名。
您可以在pillow
和numpy
(以及opencv
)之间进行转换
# 从pillow到numpy/opencvarr = numpy.array(cloth_image)# 从numpy/opencv到pillowcloth_image = Image.fromarray(arr)
(opencv
可能需要在RGB
和BGR
之间转换颜色)
最简工作代码:
from flask import Flask, requestfrom PIL import Imageapp = Flask(__name__)@app.route('/', methods=['GET', 'POST'])def index(): if request.method == 'POST': if "cloth_image" in request.files: img = request.files["cloth_image"] # 它有方法 .read() 所以可以被视为文件对象 cloth_image = Image.open(img) # 它可以使用文件对象而不是文件名 # ... 处理图像 ... return """ <form method="POST" enctype="multipart/form-data"> <input type="file" name="cloth_image"> <button type="submit">Send</button> </form>"""if __name__ == '__main__': app.run()
但是,如果您需要将其发送回去,那么您可能需要使用io.BytesIO
将图像保存到内存中的文件对象中,将其转换为base64
,并以以下方式显示
html = '<img src="data:image/png;base64,{}">'.format(data)
更复杂的代码,可以获取图像,绘制矩形并将其发送回浏览器。
from flask import Flask, requestfrom PIL import Image, ImageDrawimport ioimport base64app = Flask(__name__)@app.route('/', methods=['GET', 'POST'])def index(): img = 'empty' if request.method == 'POST': if "image" in request.files: print(request.files) # 获取图像 img = request.files["image"] # 它有方法 .read() # 读取到pillow image = Image.open(img) # 绘制一些内容 draw = ImageDraw.Draw(image) # https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html draw.rectangle([(20,20), (280,280)], outline=(255,0,0), width=3) # https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html#PIL.ImageDraw.ImageDraw.rectangle draw.text((15,5), "Hello World!") # https://pillow.readthedocs.io/en/stable/reference/ImageDraw.html#PIL.ImageDraw.ImageDraw.text # 转换为文件对象数据 obj = io.BytesIO() # 在内存中保存文件以保存图像而不使用磁盘 # image.save(obj, format='png') # 保存到文件(BytesIO) # https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.save obj.seek(0) # 转换为base64 data = obj.read() # 从文件(BytesIO)获取数据 data = base64.b64encode(data) # 转换为base64字节 data = data.decode() # 转换字节为字符串 # 转换为带嵌入图像的<img> img = '<img src="data:image/png;base64,{}">'.format(data) return '<form method="POST" enctype="multipart/form-data"><input type="file" name="image"><button type="submit">Send</button></form><br>' + imgif __name__ == '__main__': app.run()
如果您需要在不重新加载页面情况下使用它,那么您可能需要使用JavaScript。但我跳过了这个问题。