Ответ
Для отправки файлов, включая изображения, в Flask используется функция send_file. Она автоматически устанавливает необходимые HTTP-заголовки, такие как Content-Type, на основе MIME-типа файла.
1. Отправка статического файла
Это самый простой случай, когда изображение уже существует на диске.
from flask import Flask, send_file
app = Flask(__name__)
@app.route('/get-image')
def get_image():
# Путь к файлу изображения
filename = 'images/my_cat.jpg'
try:
# Отправляем файл, указывая его MIME-тип
return send_file(filename, mimetype='image/jpeg')
except FileNotFoundError:
return "File not found", 404
Почему это работает? send_file читает файл и передает его содержимое в теле HTTP-ответа, а заголовок Content-Type: image/jpeg сообщает браузеру, что нужно отобразить полученные данные как изображение.
2. Динамическая генерация и отправка изображения
Изображение можно сгенерировать на лету, например, с помощью библиотеки Pillow, и отправить его без сохранения на диск. Для этого используется объект io.BytesIO, который ведет себя как файл в памяти.
import io
from flask import Flask, send_file
from PIL import Image, ImageDraw
app = Flask(__name__)
@app.route('/generate-image')
def generate_image():
# Создаем буфер в памяти
img_io = io.BytesIO()
# Генерируем изображение 100x100 с красным квадратом
img = Image.new('RGB', (100, 100), 'blue')
draw = ImageDraw.Draw(img)
draw.rectangle([20, 20, 80, 80], fill='red')
# Сохраняем изображение в буфер в формате PNG
img.save(img_io, 'PNG')
# Перемещаем "курсор" в начало буфера
img_io.seek(0)
# Отправляем буфер как файл
return send_file(img_io, mimetype='image/png')
Рекомендации для production
В production-среде статические файлы (CSS, JS, изображения) не рекомендуется отдавать через Flask, так как это неэффективно. Вместо этого следует настроить веб-сервер (например, Nginx или Apache) для прямой отдачи статики. Это освобождает ресурсы Python-приложения для обработки динамических запросов.