Loading image from a remote server in pyglet or PIL / python

 ̄綄美尐妖づ 提交于 2019-12-11 06:03:12

问题


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?


回答1:


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)




回答2:


You can show a remote image by PIL as follows:

import requests
from PIL import Image
from StringIO import StringIO

r = requests.get('http://{}:5000/test/cat2.jpeg', stream=True)
sio = StringIO(r.raw.read())
im = Image.open(sio)
im.show()

Note that the stream=True option is necessary to create a StringIO object from the data. Also, not using io.StringIO but StringIO.StringIO.



来源:https://stackoverflow.com/questions/44636251/loading-image-from-a-remote-server-in-pyglet-or-pil-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!