Issue
I have an endpoint which downloads an image from an URL, stores it in the project directory and returns the image on the web page. But I don't want the image to be stored in my project directory. is there a way? if not, is there a way to remove the image after the method is executed?
@app.route('/get_image', methods=['GET'])
def get_image():
r = requests.get("Certain URL")
file = open("sample.png", "wb")
file.write(r.content)
file.close()
return send_file("sample.png", mimetype='image/gif')
Solution
As @TimRoberts said in comment you would have to use io.BytesIO
to create file-like object in memory, write in this file and later read from this file.
r = requests.get("https://placekitten.com/640/360")
file_like_object = io.BytesIO()
file_like_object.write(r.content)
file_like_object.seek(0) # move to the beginning of file
return send_file(file_like_object, mimetype='image/png')
or shorter
r = requests.get("https://placekitten.com/640/360")
file_like_object = io.BytesIO(r.content)
return send_file(file_like_object, mimetype='image/png')
And this can be usefull if you want to generate files instead of getting from server - ie. plot
with matplotlib
, image
with pillow
, audio
from some TextToSpeech API
, etc.
You could find many examples on Stackoverflow.
But if you don't want to edit file then there is even simpler method.
Using requests.get(..., stream=True)
you may get r.raw
which is file-like
object.
r = requests.get("https://placekitten.com/640/360", stream=True)
file_like_object = r.raw
return send_file(file_like_object, mimetype='image/png')
Minimal working code with both versions, and with real URL so everyone can copy and run it:
EDIT: I added example which resize image without saving on disk.
from flask import Flask, render_template_string, send_file
import requests
import io
from PIL import Image
app = Flask(__name__)
@app.route('/')
def index():
return render_template_string('''
<img src="/get_image">get_image<br/>
<img src="/get_image_bytesio">get_image_bytesio<br/>
<img src="/get_image_bytesio_smaller">get_image_bytesio_smaller<br/>
''')
@app.route('/get_image')
def get_image():
r = requests.get("https://placekitten.com/640/360", stream=True) # it needs `stream=True`
file_like_object = r.raw
return send_file(file_like_object, mimetype='image/png')
@app.route('/get_image_bytesio')
def get_image_bytesio():
r = requests.get("https://placebear.com/640/360")
#file_like_object = io.BytesIO()
#file_like_object.write(r.content)
#file_like_object.seek(0) # move to the beginning of file after writing
file_like_object = io.BytesIO(r.content)
return send_file(file_like_object, mimetype='image/png')
@app.route('/get_image_bytesio_smaller')
def get_image_bytesio_smaller():
r = requests.get("https://placebear.com/640/360")
file_like_object = io.BytesIO(r.content)
# edit image without saving on disk
img = Image.open(file_like_object)
img = img.resize((320, 180))
# `seek()` has to be after `resize()` because it may use `lazy loading`
file_like_object.seek(0) # move to the beginning of file after reading
img.save(file_like_object, 'PNG')
file_like_object.seek(0) # move to the beginning of file after writing
return send_file(file_like_object, mimetype='image/png')
if __name__ == '__main__':
#app.debug = True
app.run()
Answered By - furas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.