Creating an Image Without Storing It as a Local File

Render image without saving

The problem is that returning a page to the user would normally involve two requests: one for the HTML page, and one for the image itself as referenced by an img tag in that HTML. But as you say, without storing it anywhere in the meantime, the image would be lost.

There is an alternative: you can use a data uri to include the actual data for the image inline in the html. That means you won't have to persist it across requests, as everything will be returned at one. Data uris are supported in most browsers, including ie8+.

You can format the data like this, for example:

from base64 import b64encode

encoded = b64encode(img_data)
mime = "image/jpeg"
uri = "data:%s;base64,%s" % (mime, encoded)

And use it directly in the template:

<img src="{{ uri }}">

Return an image taken from an URL without storing the image file

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()

Is it possible to insert an image without using a filepath src?

Yes, see FileReader.readAsDataURL(): read file as data URI.

document.getElementById("input1").onchange = function(e) {  var someImage = e.target.files[0]  var reader = new FileReader();  var img = document.getElementById('preview');  reader.onload=function(){    img.src = reader.result  }  reader.readAsDataURL(someImage)}
<input type="file" id="input1" accept="image/*" /><img id="preview" src="" />

How to upload images directly on cloudinary without storing it into local directory?

In your example, the file is being stored to public/uploads on your server because you're telling multer to do so via multer.diskStorage

As @Molda's comment above says, you can avoid this by using the multer-storage-cloudinary package to have Multer store the file in Cloudinary automatically.

Another possibility is to change how you're using Multer so it doesn't store the file anywhere, then take the uploaded file while it's in memory and pass it to Cloudinary's SDK as a stream.

There's an example of this in this blog post on the Cloudinary site: https://cloudinary.com/blog/node_js_file_upload_to_a_local_server_or_to_the_cloud

In your case, you can stop using multer.diskStorage, in favour of just using multer() then use streamifier or another library to turn the uploaded file into a stream, and pass that to cloudinary.uploader.upload_stream()

Convert image on url to a file without saving?

In order to view an image conventionally (i.e. through a web browser, image viewer, etc), you need to have a local copy of the image.

The image initially only exists at the URL you specify, or in other words, it exists only as a file on a remote machine. In order to view it, you need to download it to a directory on the client (i.e. local) machine. This is where the URL gets "converted" into a pathname - the pathname points to the local copy of the remote image. You can think of the URL as a path to the image as well - that URL string points to where the image is.

The reason we need to download a local copy of the image is because most images are stored in a compressed format (JPEG, PNG, TIFF). These need to be decompressed in order to figure out what color each pixel is. It's not efficient to do that on the remote server, so we transfer the compressed image, store it locally, decompress it, then display it. I have to imagine that most, if not all, web browsers will actually store the image on the local disk, partly to cache the image to ensure fast loading times for subsequent views of the same webpage, and partly to minimize RAM usage.



Related Topics



Leave a reply



Submit