从pyglet或PIL/python中的远程服务器加载图像 [英] Loading image from a remote server in pyglet or PIL / python

查看:227
本文介绍了从pyglet或PIL/python中的远程服务器加载图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将远程计算机上的图像馈入pyglet(尽管我对其他平台开放,可以在这些平台上显示图像并记录用户的鼠标点击和击键).目前,我正在尝试使用远程服务器上的flask并使用requests

将其拉低

import requests

from PIL import Image
import io
import pyglet
import numpy as np

r = requests.get('http://{}:5000/test/cat2.jpeg'.format(myip),)

这不起作用:

im = pyglet.image.load(io.StringIO(r.text))

# Error: 
File "/usr/local/lib/python3.4/dist-packages/pyglet/image/__init__.py", line 178, in load
    file = open(filename, 'rb')

TypeError: invalid file: <_io.StringIO object at 0x7f6eb572bd38>

这也不起作用:

im = Image.open(io.BytesIO(r.text.encode()))

# Error:
Traceback (most recent call last):

  File "<ipython-input-68-409ca9b8f6f6>", line 1, in <module>
    im = Image.open(io.BytesIO(r.text.encode()))

  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 2274, in open
    % (filename if filename else fp))

OSError: cannot identify image file <_io.BytesIO object at 0x7f6eb5a8b6a8>

还有另一种方法可以在不将文件保存在磁盘上的情况下进行操作吗?

解决方案

第一个示例无法正常运行,因为我遇到了编码问题.但这将带您使用手动ImageData对象操作图像的方式:

import pyglet, urllib.request

# == The Web part:
img_url = 'http://hvornum.se/linux.jpg'
web_response = urllib.request.urlopen(img_url)
img_data = web_response.read()

# == Loading the image part:
window = pyglet.window.Window(fullscreen=False, width=700, height=921)
image = pyglet.sprite.Sprite(pyglet.image.ImageData(700, 921, 'RGB', img_data))

# == Stuff to render the image:
@window.event
def on_draw():
    window.clear()
    image.draw()
    window.flip()

@window.event
def on_close():
    print("I'm closing now")

pyglet.app.run()

现在,更方便,更省力的处理方式是使用io.BytesIO虚拟文件句柄,并使用参数file=dummyFile将其扔入pyglet.image.load()中,如下所示:

import pyglet, urllib.request
from io import BytesIO

# == The Web part:
img_url = 'http://hvornum.se/linux.jpg'
web_response = urllib.request.urlopen(img_url)
img_data = web_response.read()
dummy_file = BytesIO(img_data)

# == Loading the image part:
window = pyglet.window.Window(fullscreen=False, width=700, height=921)
image = pyglet.sprite.Sprite(pyglet.image.load('noname.jpg', file=dummy_file))

# == Stuff to render the image:
@window.event
def on_draw():
    window.clear()
    image.draw()
    window.flip()

@window.event
def on_close():
    print("I'm closing now")

pyglet.app.run()

对我有效,而且速度也很快.
最后一点,请尝试将图像放入pyglet.sprite.Sprite对象中,它们往往更快,更易于使用,并为您提供了很多漂亮的功能(例如,轻松定位,spr.scale和旋转功能)

I would like to feed images from a remote machine into pyglet (though I am open to other platforms where I can present images and record user's mouse clicks and keystrokes). Currently I am trying to do it using flask on the remote server and pulling it down with requests

import requests

from PIL import Image
import io
import pyglet
import numpy as np

r = requests.get('http://{}:5000/test/cat2.jpeg'.format(myip),)

This does not work:

im = pyglet.image.load(io.StringIO(r.text))

# Error: 
File "/usr/local/lib/python3.4/dist-packages/pyglet/image/__init__.py", line 178, in load
    file = open(filename, 'rb')

TypeError: invalid file: <_io.StringIO object at 0x7f6eb572bd38>

This also does not work:

im = Image.open(io.BytesIO(r.text.encode()))

# Error:
Traceback (most recent call last):

  File "<ipython-input-68-409ca9b8f6f6>", line 1, in <module>
    im = Image.open(io.BytesIO(r.text.encode()))

  File "/usr/local/lib/python3.4/dist-packages/PIL/Image.py", line 2274, in open
    % (filename if filename else fp))

OSError: cannot identify image file <_io.BytesIO object at 0x7f6eb5a8b6a8>

Is there another way to do it without saving files on disk?

解决方案

The first example isn't working properly because I'm having encoding issues. But this will get you on the way of using manual ImageData objects to manipulate images:

import pyglet, urllib.request

# == The Web part:
img_url = 'http://hvornum.se/linux.jpg'
web_response = urllib.request.urlopen(img_url)
img_data = web_response.read()

# == Loading the image part:
window = pyglet.window.Window(fullscreen=False, width=700, height=921)
image = pyglet.sprite.Sprite(pyglet.image.ImageData(700, 921, 'RGB', img_data))

# == Stuff to render the image:
@window.event
def on_draw():
    window.clear()
    image.draw()
    window.flip()

@window.event
def on_close():
    print("I'm closing now")

pyglet.app.run()

Now to the more convenient, less manual way of doing things would be to use the io.BytesIO dummy file-handle and toss that into pyglet.image.load() with the parameter file=dummyFile like so:

import pyglet, urllib.request
from io import BytesIO

# == The Web part:
img_url = 'http://hvornum.se/linux.jpg'
web_response = urllib.request.urlopen(img_url)
img_data = web_response.read()
dummy_file = BytesIO(img_data)

# == Loading the image part:
window = pyglet.window.Window(fullscreen=False, width=700, height=921)
image = pyglet.sprite.Sprite(pyglet.image.load('noname.jpg', file=dummy_file))

# == Stuff to render the image:
@window.event
def on_draw():
    window.clear()
    image.draw()
    window.flip()

@window.event
def on_close():
    print("I'm closing now")

pyglet.app.run()

Works on my end and is rather quick as well.
One last note, try putting images into pyglet.sprite.Sprite objects, they tend to be quicker, easier to work with and gives you a whole bunch of nifty functions to work with (such as easy positioning, spr.scale and rotate functions)

这篇关于从pyglet或PIL/python中的远程服务器加载图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆