服务图像使用龙卷风没有文件I/O



我试图使用龙卷风库提供网络摄像头图像,但我发现的唯一方法是先保存图像,然后返回图像名称。

是否有一种方法可以在不保存到磁盘的情况下提供图像?

import tornado.ioloop
import tornado.web
import pygame.camera
import pygame.image
from time import time
from io import StringIO
pygame.camera.init()
cam = pygame.camera.Camera(pygame.camera.list_cameras()[0])
cam.start()
class MainHandler(tornado.web.RequestHandler):
    def get(self):

        img = cam.get_image()
        name = str( round( time() ) )
        name = name + '.jpg'
        pygame.image.save(img, name)

        self.write('<img src="' + name + '">')

application = tornado.web.Application([
    (r"/", MainHandler),
    (r'/(.*)', tornado.web.StaticFileHandler, {'path': ''})
])
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

看起来pygame不支持将图像保存到类文件对象,所以您将无法直接使用它。然而,它确实有一个tostring方法。该文档指出,它允许与其他图像库互操作:

创建一个可以使用' fromstring '方法传输的字符串

所以,你可以使用tostring将你的图像转换为字符串,然后使用另一个支持将图像写入类文件对象的Python库,并使用其fromstring方法,

下面是一个使用pillow作为备选图像库的示例。

import tornado.ioloop
import tornado.web
from PIL import Image
import cStringIO as StringIO
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("<img src='http://localhost:8888/img'>")
class ImgHandler(tornado.web.RequestHandler):
    img_name = "bg.jpg"
    img = pygame.image.load(img_name)
    str_img = pygame.image.tostring(img, "RGB")
    size = img.get_size()
    fimg = Image.frombytes("RGB", size, str_img, "raw")
    fobj = StringIO.StringIO()
    fimg.save(fobj, format="png")  #jpeg encoder isn't available in my install...
    for line in fobj.getvalue():
        self.write(line)
    self.set_header("Content-type",  "image/png")

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/img", ImgHandler),
    #(r'/(.*)', tornado.web.StaticFileHandler, {'path': ''})
])
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

localhost:8888localhost:8888/img都将显示图像

是的,您可以在不处理File I/O的情况下提供图像。我有一个python3应用程序,通过使用Tornado

发送1x1像素来跟踪用户。

我将图像存储在源代码中:

# 1x1 Transparent Pixel in HEX Format
pixel_GIF = [0x47,0x49,0x46,0x38,0x39,0x61,
             0x01,0x00,0x01,0x00,0x80,0x00,
             0x00,0x00,0x00,0x00,0xff,0xff,
             0xff,0x21,0xf9,0x04,0x01,0x00,
             0x00,0x00,0x00,0x2c,0x00,0x00,
             0x00,0x00,0x01,0x00,0x01,0x00, 
             0x00,0x02,0x01,0x44,0x00,0x3b]

然后,我使用以下函数将HEX格式的图像转换为二进制:

def pack_into_binary(data):
    """Convert given data into binary form"""
    packed = str()
    for datum in data:
        packed += struct.pack('B', datum).decode("ISO-8859-1")
    return packed
pixel_binary = pack_into_binary(pixel_GIF)

之后,我设置适当的标题,并提供图像:

#1x1 Transparent Tracking Pixel
self.set_header("Content-Length", 42)
self.set_header("Content-Type", "image/gif")
self.set_header("Pragma", "no-cache")
self.set_header("Cache-Control", 
                "no-store, "
                "no-cache=Set-Cookie, "
                "proxy-revalidate, "
                "max-age=0, "
                "post-check=0, pre-check=0"
                )
self.set_header("Expires", "Wed, 2 Dec 1837 21:00:12 GMT")
self.write(self.pixel_binary)

不做任何File I/O .

注意:在您的情况下,如果您有内存中的图像,您可以通过将格式转换为二进制并使用write方法来提供它。不同的是,你的形象不是预先确定的,不像我。

Edit:查看下面从RGB Surfacebinary编码的转换示例

from StringIO import StringIO
from PIL import Image
data = pygame.image.tostring(cam.get_image(),"RGB")
img = Image.fromstring('RGBA', (100,200), data) # 100 x 200 example surface
zdata = StringIO()
img.save(zdata, 'JPEG')
self.write(zdata.getvalue())

那么你可以使用Tornado来服务image

当然!比如:

class ImageHandler(tornado.web.RequestHandler):
    def get(self):
        img = cam.get_image()
        self.set_header('Content-Type', 'image/jpg')
        self.write(img.contents)
application = tornado.web.Application([
    (r"/image.jpg", ImageHandler),
])

我不知道如何得到图像的内容作为字节,但你得到的想法。

最新更新