[英]Python3.5 send object over socket (Pygame cam image)
我想使用Python 3.5通過套接字發送PyGame圖像,但我總是遇到一個錯誤。
我得到圖像,將其腌制,然后發送。
在客戶那里,我收到了它,給它解開了皮,然后給了我看。
但是我有一個錯誤:
fenetre.blit(img, (20, 30)) pygame.error: display Surface quit
這是我的服務器代碼(一個發送圖像):
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0", (680, 480))
cam.start()
class Streaming(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
s = socket.socket()
s.bind(('192.168.1.158', 12801))
s.listen(1)
while True:
sc, info = s.accept()
print("Video client connected : "+str(info))
try:
while True:
image = cam.get_image()
str_img = pickle.dumps(image)
sc.send(str_img)
print(str_img)
print("Sending Image")
time.sleep(0.005)
except Exception as e:
print(str(e))
和客戶端的代碼:
fenetre = pygame.display.set_mode((900, 900))
class Receiving(Thread):
def __init__(self):
Thread.__init__(self)
self.clock = pygame.time.Clock()
def run(self):
global fenetre
si = socket.socket()
si.connect(("192.168.1.158", 12801))
while True:
img = si.recv(4096)
img = pickle.loads(img)
fenetre.blit(img, (20, 30))
pygame.display.flip()
self.clock.tick(60)
預先感謝 !
我以發送當前時間的表面為例。
(Pygame無法與我的相機配合使用)。
它使用struc.pack()
在發送圖像之前始終以4個字節發送圖像大小。 因此,客戶端首先接收4個字節並具有圖像大小。 然后,它可以使用此信息來接收圖像。
兩者都使用循環來始終發送/接收。
server.py
#!/usr/bin/env python
import pygame
from threading import Thread
import socket
import struct # to send `int` as `4 bytes`
import time # for test
# --- constants ---
ADDRESS = ("localhost", 12801)
SURFACE_SIZE = (640, 480)
WHITE = (255, 255, 255)
BLACK = ( 0, 0, 0)
GREEN = ( 0, 255, 0)
# --- classes ---
class Streaming(Thread):
def __init__(self):
Thread.__init__(self)
pygame.init()
#pygame.camera.init()
#self.cam = pygame.camera.Camera("/dev/video0", SURFACE_SIZE)
#self.cam.start()
# create surface to imitate camera image
self.image = pygame.Surface(SURFACE_SIZE)
self.image_rect = self.image.get_rect()
# create font to display text on surface
self.font = pygame.font.Font(None, 50)
def get_image(self):
# emulate cam.get_image()
# get current time as string
current_time = time.strftime('%H:%M:%S.%s')
# render surface with text (and center it)
text = self.font.render(current_time, True, BLACK, GREEN)
text_rect = text.get_rect(center=self.image_rect.center)
# clear image and put new text
self.image.fill(WHITE)
self.image.blit(text, text_rect)
return self.image
def run(self):
s = socket.socket()
# solution for: "socket.error: [Errno 98] Address already in use"
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(ADDRESS)
s.listen(1)
print("Wait for connection")
try:
sc, info = s.accept()
print("Video client connected:", info)
while True:
# get image surface
#image = self.cam.get_image()
image = self.get_image()
# convert surface to string
img_str = pygame.image.tostring(image, 'RGB')
print('len:', len(img_str))
# send string size
len_str = struct.pack('!i', len(img_str))
sc.send(len_str)
# send string image
sc.send(img_str)
# wait
time.sleep(0.5)
except Exception as e:
print(e)
finally:
# exit
print("Closing socket and exit")
sc.close()
s.close()
pygame.quit()
# --- main ---
Streaming().run()
client.py
#!/usr/bin/env python
import pygame
from threading import Thread
import socket
import struct
# --- constants ---
ADDRESS = ("localhost", 12801)
SURFACE_SIZE = (640, 480)
# --- classes ---
class Receiving(Thread):
def __init__(self):
Thread.__init__(self)
pygame.init()
self.screen = pygame.display.set_mode((800, 600))
self.screen_rect = self.screen.get_rect()
self.clock = pygame.time.Clock()
def run(self):
s = socket.socket()
s.connect(ADDRESS)
try:
running = True
while running:
# receive size
len_str = s.recv(4)
size = struct.unpack('!i', len_str)[0]
print('size:', size)
# receive string
img_str = b''
while size > 0:
if size >= 4096:
data = s.recv(4096)
else:
data = s.recv(size)
if not data:
break
size -= len(data)
img_str += data
print('len:', len(img_str))
# convert string to surface
image = pygame.image.fromstring(img_str, SURFACE_SIZE, 'RGB')
image_rect = image.get_rect(center=self.screen_rect.center)
# blit
self.screen.blit(image, image_rect)
pygame.display.flip()
#self.clock.tick(30)
# wait for ESC or close window
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
except Exception as e:
print(e)
finally:
# exit
print("Closing socket and exit")
s.close()
pygame.quit()
# --- main ---
Receiving().run()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.