枕头属性错误

Pillow Attribute Error

我想设置一个从我的 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()

但它 returns 我遵循错误代码:

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'

我该如何解决这个问题?

我没有 raspberry-pi,但决定看看我是否可以重现该问题。此外,对于输入,我刚刚在磁盘上创建了一个图像文件以消除所有套接字内容。果然,我遇到了与您遇到的完全相同的错误。 (注意: IMO 你应该自己做这个简化并发布一个 MCVE 来说明这个问题(参见 SO 帮助中心的 How to create a Minimal, Complete, and Verifiable example)。

为了解决问题,我在 Image.open() 语句之后立即添加了对 image.load() 方法的调用,事情开始起作用了。不仅错误消失了,而且输出文件看起来也很好。

这是我的简单测试代码,其中指出了修复:

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 image_file:
    image_stream.write(image_file.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 documentationPIL.Image.open() 函数的这段话:

This is a lazy operation; this function identifies the file, but the file remains open and the actual image data is not read from the file until you try to process the data (or call the load() method).

强调我的。您可能会认为 image.verify() 会使这变得不必要,因为似乎验证 "file" 需要加载图像数据以检查其内容(根据该方法自己的 documentation,它声称它 "verifies the contents of a file")。我猜这可能是一个错误,您应该报告它。