我想设置从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()
但它返回我的错误代码:
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'
我该如何解决这个问题?
答案 0 :(得分:3)
我没有树莓派,但决定看看我是否可以重现这个问题。此外,对于输入我刚刚在磁盘上创建了一个图像文件,以消除所有套接字的东西。果然我遇到了与你遇到的完全相同的错误。 (注意: IMO您应该自己进行此简化并发布说明问题的MCVE(请参阅SO帮助中心内的How to create a Minimal, Complete, and Verifiable example)。
为了解决问题,我在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 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')
线索是来自PIL.Image.open()
load()
函数的pillow documentation的这段话:
这是一个懒惰的操作;此函数标识文件,但文件 在您尝试之前,不会从文件中读取实际图像数据 处理数据(或调用
image.verify()
方法)。
强调我的。您会认为with open("input.txt", 'r') as file:
line = file.read()
line = line.split()
count = 0
output = open("output.txt", 'w')
for i in line:
output.write(i)
output.write(" ")
count+=1
if count == 9:
output.write("\n")
count = 0
output.close()
会使这不必要,因为似乎验证“文件”需要加载图像数据以检查其内容(根据该方法自己的documentation,它声称它“验证文件的内容“)。我猜这可能是一个错误,你应该报告它。