【问题标题】:Send PIL image object from socket client to socket server将 PIL 图像对象从套接字客户端发送到套接字服务器
【发布时间】:2015-03-18 10:21:26
【问题描述】:

我想将 PIL 图像对象从套接字客户端发送到套接字服务器。由于我无法直接通过套接字发送图像对象,因此我使用 numpy 将其转换为数组,然后尝试将数组发送到套接字服务器。

这是我的服务器程序(time 只是为了在每次保存文件时获取文件的新名称):

import socket
import time
import os
import sys
import Image
import ImageGrab
import numpy

sd='C:\Users\Saurabh\Desktop'
s=socket.socket()
host=socket.gethostname()          #'WarMachine'
port=12300
s.bind((host,port))

s.listen(9)

while True:
    a,addr=s.accept()
    print "got connection from",addr
    a.send("1")
    imgarr=a.recvfrom(4096)
    img=Image.fromarray(numpy.uint8(imgarr))
    sec=time.time()
    lc=time.localtime(sec)
    t=time.asctime(lc)
    print t
    strng=""+t[8:10]+"_"+t[11:13]+"_"+t[14:16]+"_"+t[17:19]
    saveas=os.path.join(sd, 'ScreenShot_'+strng+'.jpg')
    img.save(saveas)
    print "run successful server"
    a.close()

上面提到的客户端程序的错误是:

got connection from ('192.168.1.9', 50903)
Traceback (most recent call last):
  File "C:/Users/Saurabh/PycharmProjects/MajorProject/srvr.py", line 26, in <module>
    img=Image.fromarray(numpy.uint8(imgstr))
ValueError: invalid literal for long() with base 10: ''

这是客户端程序:

import os
import sys
import time
import Image
import ImageGrab
import subprocess
import socket
import numpy

s=socket.socket()
host="WarMachine"     #use same hostname as server or else it wont work
port=12300
s.connect((host,port))

def shtDwn():
    time = 10
    subprocess.call(["shutdown.exe", "/s"])

def screenShot():
    sd='C:\Users\Saurabh\Desktop'

    img=ImageGrab.grab()
    imgarr=numpy.asarray(img)
    s.send(imgarr)
    print "run successful screentest1"


ip=s.recv(1024) 
#this receives 1 sent from server to activate snapshot function

if (ip=="1"):
    for i in range(0,10):
        screenShot()
        time.sleep(5)
elif(ip=="2"):
    shtDwn()
else:
    print"Wrong Input"

我在上面的客户端程序中遇到的错误是:

run successful screentest1
Traceback (most recent call last):
  File "C:/Users/Saurabh/PycharmProjects/MajorProject/ScreenTest1.py", line 42, in <module>
    screenShot()
  File "C:/Users/Saurabh/PycharmProjects/MajorProject/ScreenTest1.py", line 27, in screenShot
    s.sendto(imgarr,("WarMachine",12300))
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host

顺便说一下,我在使用下面的程序之前已经保存了图像,但我不知道我上面的程序有什么问题。

之前没有客户端和服务器的程序:

import os
import sys
import Image
import time
import ImageGrab
import numpy


sd='C:\Users\Saurabh\Desktop'

img=ImageGrab.grab()
imgarr=numpy.asarray(img)
print imgarr
img2=Image.fromarray(numpy.uint8(imgarr))
sec=time.time()
lc=time.localtime(sec)
t=time.asctime(lc)
print t
strng=""+t[8:10]+"_"+t[11:13]+"_"+t[14:16]+"_"+t[17:19]
saveas=os.path.join(sd, 'ScreenShot_'+strng+'.jpg')
#img.save(saveas)
img2.save(saveas)
print "run successful"

【问题讨论】:

  • 您的代码在什么意义上不起作用?如果您遇到异常,请在您的问题中发布完整的回溯。
  • 是的,我遇到了一个异常,同时在客户端程序中执行“s.sendto(imgarr("WarMachine",12300))”,该程序用于发送类型为“numpy array”转换的 imgarr从图像对象。使用“img=Image.fromarray(numpy.uint8(imgarr))”将接收到的 imgarr 转换为图像对象时出现异常,该异常应该将数组转换为图像对象(如下面的工作程序中所述)。
  • 我已经对问题进行了修改,您可以看看它
  • 基于该错误,它看起来好像您的客户端正在接收一个空字符串而不是一个数组(我不明白为什么相应的变量在回溯中被命名为 imgstr 而在您在上面发布的服务器代码)。我怀疑问题是您需要在通过套接字发送数组之前对其进行序列化,例如使用np.tostringnp.fromstring,如this answer 中所述。
  • 谢谢伙计,我会告诉你它是否有效。 TY

标签: python sockets numpy python-imaging-library


【解决方案1】:

好吧,我也一直在研究这个问题,并发现您可以通过将图像转换为 numpy 数组来通过套接字发送图像。

这是示例代码-

#Host Side script
#Host will be sending the screen to client.

import numpy as np 
import socket
from PIL import ImageGrab

filename = 'host_data.npy'

print("started.\nListening for connections...")
s = socket.socket()
s.bind((socket.gethostname(), 1234))
s.listen(0)

conn, addr = s.accept()
print('connection established.')

img = np.array(ImageGrab.grab())
np.save(filename, img)
file = open(filename, 'rb')
data = file.read(1024)
conn.send(data)

while data != b'':
    data = file.read(1024)
    conn.send(data)

print('data has been successfully transmitted.')
#This is client side script

import socket
import numpy as np 
import cv2

s = socket.socket()
s.connect((socket.gethostname(), 1234))
print("connected.")

filename = 'client_data.npy'
file = open(filename, 'wb')

data = s.recv(1024)
file.write(data)

while data != b'':
    data = s.recv(1024)
    file.write(data)
file.close()

o_file = np.load(filename)
o_file = cv2.cvtColor(o_file, cv2.COLOR_BGR2RGB)
cv2.imshow('transferred file', o_file)
cv2.waitKey(0)

我所做的只是,使用np.save(filename) 将numpy 数组保存在npy 文件中,并以字节格式发送npy 文件的内容。然后客户端收到内容并制作另一个npy类型的文件并加载数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 2019-06-03
    • 2017-05-26
    • 2013-04-01
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    相关资源
    最近更新 更多