Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
二进制数据到图像原始python_Python_Image_Networking_Binary - Fatal编程技术网

二进制数据到图像原始python

二进制数据到图像原始python,python,image,networking,binary,Python,Image,Networking,Binary,下面是我想做的: 此映像服务器将在端口5003上发送数据 它将传输的数据格式如下 图像类型为1字节(0=raw,1=JPEG) 然后是图像大小的下一个4字节 然后,将有n个字节,顺序如下 宽度为2字节,高度为2字节,B为1字节,R为1字节,G为1字节 所以我要做的是获取数据并用以下代码将其转换为图像: #! /usr/bin/python import socket import sys import binascii from PIL import Image from StringIO im

下面是我想做的: 此映像服务器将在端口5003上发送数据 它将传输的数据格式如下 图像类型为1字节(0=raw,1=JPEG) 然后是图像大小的下一个4字节 然后,将有n个字节,顺序如下 宽度为2字节,高度为2字节,B为1字节,R为1字节,G为1字节

所以我要做的是获取数据并用以下代码将其转换为图像:

#! /usr/bin/python
import socket
import sys
import binascii
from PIL import Image
from StringIO import StringIO


# Connect to the server image
serverHost = 'localhost'
serverPort = 5003
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((serverHost, serverPort))

print >>sys.stderr, 'Connecting to host: ' +  str(serverHost) 
print >>sys.stderr, 'and server Port: ' + str(serverPort)

s.settimeout(1)

#Receive the image type
imageType = s.recv(1)
print>>sys.stderr, 'received %r' %binascii.hexlify(imageType)
print>>sys.stderr, 'Unpacked: ', int(binascii.hexlify(imageType), 16)
received = imageType.__len__()
print>> sys.stderr, "Received: ", received 

#Receive the image size
imageSize = s.recv(4)
print>>sys.stderr, 'received %r' %binascii.hexlify(imageSize)
print>>sys.stderr, 'Unpacked: ', int(binascii.hexlify(imageSize), 16)
received = imageSize.__len__()
print>> sys.stderr, "Received: ", received 


#Receive the image Data
imageData = ''
received =0
while(received < int(binascii.hexlify(imageSize), 16)):
  buffer = s.recv(4096)
  imageData += buffer
  received += buffer.__len__()
  print>> sys.stderr, "Received: ", received 

img = Image.fromstring('RGB', (1280, 720), imageData, 'raw')

#img = Image.open(StringIO(binascii.hexlify(imageData)))
img = img.convert('RGB')
img.save('out.png')

#file = open('test.png', 'w');
#file.write(imageData)
#file.close()

#When we receive the image, we send the acknowledgement
s.send('OK')
s.close()`enter code here`
如果有变化呢

img = Image.fromstring('RGB', (1280, 720), imageData, 'raw')

我得到这个错误:

Value error: Unrecognized mode,

有人知道如何解决这类问题吗?

当服务器和客户机的代码都已完全给出(但简化为仅显示问题)时,最好调试这些问题

下面是一个基于您的初始代码和描述的非常基本的客户端。请注意,没有使用
image\u type
,只是因为您提到要区分JPEG和RAW。我总是假设接收到的数据是RGB数据,您可以根据实际问题进行调整。这里的主要区别是使用了
struct
,这是一种标准的方法,可以将数据打包成通用格式,通过网络发送,并避免与字节排序相关的问题。此代码还希望接收图像宽度和高度(代码中未显示),以便您可以在客户端重建图像

import socket
import struct
from PIL import Image

def recv(sock, size):
    data = ''
    to_receive = size
    while to_receive > 0:
        data += sock.recv(size)
        to_receive = size - len(data)
    return data

serv_host = ''
serv_port = 5003

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((serv_host, serv_port))

s.settimeout(1)

image_type = struct.unpack('!b', recv(s, 1))[0]
print "Image type: %d" % image_type
image_size = struct.unpack('!i', recv(s, 4))[0]
print "Image size: %d" % image_size
image_width, image_height = struct.unpack('!hh', recv(s, 4))
print "Image dimensions: %d x %d" % (image_width, image_height)

# Receive image data
image_data = recv(s, image_size)
print len(image_data)

# When we receive the image, we send the acknowledgement.
s.send('OK')
s.close()

img = Image.fromstring('RGB', (image_width, image_height), image_data)
img.save('out.png')
由于没有包括服务器,下面是一个简单的协议,它尊重您描述的协议。我没有检查服务器中是否已完全接收数据。还请注意,此服务器仅提供运行时在命令行中指定的单个映像。再一次,适应你的问题。还要注意,我没有发送图像模式,这在实际应用中可能是一个问题

import sys
import socket
import struct
from PIL import Image

host = ''
port = 5003
backlog = 5

serv_img = Image.open(sys.argv[1])
simg_size = serv_img.size
serv_data = serv_img.tostring()
data_size = len(serv_data)

print "Serving data of size %d" % data_size

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(backlog)
while True:
    client, address = s.accept()

    client.sendall(struct.pack('!b', 1))
    client.sendall(struct.pack('!i', data_size))
    client.sendall(struct.pack('!hh', *simg_size))
    client.sendall(serv_data)

    data = client.recv(2)
    if data == 'OK':
        print "OK", address

    client.close()

关于不使用
\uuuu len\uuuu
的提示仅仅是因为它是Python中的一个特殊方法,被
len
本身调用。如果您没有任何充分的理由使用特殊方法,那么就不要这样做。

您提到过使用USARSim的图像服务器。下面是我用来从USARSim(UT2004版本)接收图像的代码:

def get_图像(sock):
image_type=struct.unpack('b',sock.recv(1))[0]
image_size=struct.unpack('>i',sock.recv(4))[0]
如果图像大小小于250000:
image_data=“”
已接收=0
同时(接收<图像大小):
数据=sock.recv(图像大小已接收)
接收+=len(数据)
图像_数据+=数据
filename=“image\u%s.jpg”%str(现在())
将open(文件名,“wb”)作为f:
f、 写入(图像数据)
def写入确认(sock):
sock.send(“确定”)
def main():
sock=socket.socket(socket.AF\u INET,socket.sock\u流)
sock.connect((主机、端口))
尽管如此:
获取图像(sock)
写入确认(sock)

第二个错误很简单,因为PIL不支持从字符串创建图像的“BRG”。第一个错误是由于没有足够的图像数据来构建1280*720的图像。检查len(imageData)=宽度*高度*数字通道。另外,为什么不使用
struct
?除此之外,另一个可能的错误源是服务器,它不是由您提供的。作为建议,您还需要发送图像模式,否则您将如何知道您是否有“L”、“RGB”和其他模式,因为原始jpg中的模式?除了@mmgp所说的(+1 on
struct
module),您可能需要多次调用s.recv(),即
s.recv(4)
可能返回少于4字节(您可以调用
f=s.makefile('rb');f.read(4)
以确保读取了4个字节或遇到了EOF。使用
len(buff)
而不是
buff。
您提到了“2个字节代表宽度,2个字节代表高度”,但我不认为它是recv()ed?mmgp:是的,在我将图像从1280x720调整到320x240后,错误就不再存在了。实际上这是我第一次使用Python,所以你能解释一下如何使用struct吗?对于服务器本身,它来自USARSim image server。它提供了关于它将发送什么图像和图像类型的信息J.F.Sebastian,我想我试试看,顺便问一下,蓝(buff)和蓝(buff)的区别是什么?\uuuu蓝(buff()?ArminRigo对于这一部分,我只是从互联网上复制了一段代码,另一个原因是我不知道如何根据上面的信息构建图像,
import socket
import struct
from PIL import Image

def recv(sock, size):
    data = ''
    to_receive = size
    while to_receive > 0:
        data += sock.recv(size)
        to_receive = size - len(data)
    return data

serv_host = ''
serv_port = 5003

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((serv_host, serv_port))

s.settimeout(1)

image_type = struct.unpack('!b', recv(s, 1))[0]
print "Image type: %d" % image_type
image_size = struct.unpack('!i', recv(s, 4))[0]
print "Image size: %d" % image_size
image_width, image_height = struct.unpack('!hh', recv(s, 4))
print "Image dimensions: %d x %d" % (image_width, image_height)

# Receive image data
image_data = recv(s, image_size)
print len(image_data)

# When we receive the image, we send the acknowledgement.
s.send('OK')
s.close()

img = Image.fromstring('RGB', (image_width, image_height), image_data)
img.save('out.png')
import sys
import socket
import struct
from PIL import Image

host = ''
port = 5003
backlog = 5

serv_img = Image.open(sys.argv[1])
simg_size = serv_img.size
serv_data = serv_img.tostring()
data_size = len(serv_data)

print "Serving data of size %d" % data_size

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(backlog)
while True:
    client, address = s.accept()

    client.sendall(struct.pack('!b', 1))
    client.sendall(struct.pack('!i', data_size))
    client.sendall(struct.pack('!hh', *simg_size))
    client.sendall(serv_data)

    data = client.recv(2)
    if data == 'OK':
        print "OK", address

    client.close()
def get_image(sock):    
    image_type = struct.unpack('b', sock.recv(1))[0]    
    image_size = struct.unpack('>i', sock.recv(4))[0]

    if image_size < 250000:      
        image_data = ""
        received = 0
        while (received < image_size):
            data = sock.recv(image_size-received)
            received += len(data)
            image_data += data        

        filename = "image_%s.jpg" % str(now())
        with open(filename, "wb") as f:
            f.write(image_data)

def write_ack(sock):
    sock.send("OK")

def main():
   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   sock.connect((host, port))

   while True:
       get_image(sock)
       write_ack(sock)