2016-07-30 5 views
3

Я хочу настроить imagestream из моего rbpi на свой сервер.Ошибка атрибута подушки

Поэтому я хотел бы настроить сетевой поток, указанный в файле http://picamera.readthedocs.io/en/release-1.12/recipes1.html#streaming-capture.

Это сработало хорошо, но теперь я хочу сохранить захваченное изображение.

-> (модифицированный скрипт сервера)

import io 
import socket 
import struct 
from PIL import Image 

# Start a socket listening for connections on 0.0.0.0:8000 (0.0.0.0 means 
# all interfaces) 
server_socket = socket.socket() 
server_socket.bind(('0.0.0.0', 8000)) 
server_socket.listen(0) 

# Accept a single connection and make a file-like object out of it 
connection = server_socket.accept()[0].makefile('rb') 
try: 
    while True: 
     # Read the length of the image as a 32-bit unsigned int. If the 
     # length is zero, quit the loop 
     image_len = struct.unpack('<L', connection.read(struct.calcsize('<L')))[0] 
     if not image_len: 
      break 
     # Construct a stream to hold the image data and read the image 
     # data from the connection 
     image_stream = io.BytesIO() 
     image_stream.write(connection.read(image_len)) 
     # Rewind the stream, open it as an image with PIL and do some 
     # processing on it 
     image_stream.seek(0) 
     image = Image.open(image_stream) 
     print('Image is %dx%d' % image.size) 
     image.verify() 
     print('Image is verified') 
     im = Image.new("RGB", (640,480), "black") #the saving part 
     im = image.copy() 
     im.save("./img/test.jpg","JPEG") 
finally: 
    connection.close() 
    server_socket.close() 

Но он возвращает мне следующую ERRORCODE:

Traceback (most recent call last): 
    File "stream.py", line 33, in <module> 
    im = image.copy() 
    File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 781, in copy 
    self.load() 
    File "/usr/lib/python2.7/dist-packages/PIL/ImageFile.py", line 172, in load 
    read = self.fp.read 
AttributeError: 'NoneType' object has no attribute 'read' 

Как я могу это исправить?

+1

Возможно, вам придется вызвать 'image.load()' перед 'image.copy()'. Документы делают этот звук ненужным, но у Pillow, как известно, есть ошибки ... – martineau

+0

Это уменьшает ошибку в строке 781. Но вторая ошибка все еще существует. – Meitoasty

ответ

2

У меня нет малины-пи, но я решил посмотреть, смогу ли я воспроизвести проблему в любом случае. Кроме того, для ввода я только что создал файл образа на диске, чтобы устранить все содержимое сокета. Разумеется, я получил точно такую ​​же ошибку, как вы столкнулись. (Примечание: ИМО вы должны сделать это упрощение самостоятельно и отправил MCVE иллюстрирующую проблему (см How to create a Minimal, Complete, and Verifiable example в SO справочном центре)

Чтобы получить эту проблему, чтобы уйти, я добавил вызов метода image.load() немедленно. . после того, как Image.open() заявление и все начало работать не только была ошибка исчезла, а выходной файл, казалось хорошо, слишком

Вот мой простой тестовый код с исправлением указано:.

import io 
import os 
from PIL import Image 

image_filename = 'pillow_test.jpg' 

image_len = os.stat(image_filename).st_size 
image_stream = io.BytesIO() 
with open(image_filename, 'rb') as imagefile: 
    image_stream.write(imagefile.read(image_len)) 
image_stream.seek(0) 
image = Image.open(image_stream) 
image.load() ########## ADDED LINE ########## 
print('Image is %dx%d' % image.size) 
image.verify() 
print('Image is verified') 
im = Image.new("RGB", (640,480), "black") #the saving part 
im = image.copy() 
im.save("pillow_test_out.jpg","JPEG") 
print('image written') 

ключ был этот отрывок из pillow documentation для функции PIL.Image.open():

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

(курсив мой) Вы бы думаете, что image.verify() сделает это ненужное, так как, похоже, проверяющие «файл» потребует загрузок данных, чтобы проверить его. Я предполагаю, что это, скорее всего, ошибка, и вы должны сообщить об этом.