Как возвратить изображение в ответе HTTP с CherryPy

У меня есть код, который генерирует Каир ImageSurface, и я выставляю его как так:

def preview(...):
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
    ...
    cherrypy.response.headers['Content-Type'] = "image/png"
    return surface.get_data()
preview.exposed = True

Это не работает (браузеры сообщают, что изображение имеет ошибки).

Я протестировал это surface.write_to_png('test.png') работы, но я не уверен, что вывести данные в возвратить его. Я предполагаю некоторый подобный файлу объект? Согласно pycairo документации, get_data() возвращает буфер. Я также теперь попробовал:

tempf = os.tmpfile()
surface.write_to_png(tempf)
return tempf

Кроме того, лучше создать и содержать это изображение в памяти (как, я пытаюсь сделать), или запишите это в диск как временный файл и служите ему оттуда? Мне только нужно изображение однажды, затем оно может быть отброшено.

7
задан colinmarc 17 June 2010 в 19:05
поделиться

3 ответа

Добавьте эти импорты:

from cherrypy.lib import file_generator
import StringIO

, а затем выполните следующее:

def index(self):
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
    cherrypy.response.headers['Content-Type'] = "image/png"

    buffer = StringIO.StringIO()
    surface.write_to_png(buffer)
    buffer.seek(0)

    return file_generator(buffer)

Дополнительно, если вы обслуживаете отдельный файл (т.е. он не является частью веб-страницы), и вы этого не делаете. Если вы хотите, чтобы он отображался в браузере, а обрабатывался как файл для сохранения на диске, вам понадобится еще один заголовок:

cherrypy.response.headers['Content-Disposition'] = 'attachment; filename="file.png"'

Кроме того, лучше ли создать и удерживать это изображение в памяти (как будто я пытаюсь делать) или записать на диск в качестве временного файл и обслуживать его оттуда? только я нужно изображение один раз, тогда это может быть отброшен.

Если единственное, что вы хотите сделать, это передать этот файл браузеру, нет причин создавать его на диске на сервере.Напротив, помните, что доступ к жесткому диску снижает производительность.

17
ответ дан 6 December 2019 в 10:47
поделиться

Вы пробовали return str (surface.get_data ()) ?

0
ответ дан 6 December 2019 в 10:47
поделиться

Попробуйте это для подхода «файл в памяти»

return StringIO.StringIO(surface.get_data())
0
ответ дан 6 December 2019 в 10:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: