Données binaires pour l'image raw python

Alors, c'est ce que j'essaie de faire:
Il y a ce serveur d'images qui enverra des données au port. 5003
Le format de données qu'il transmettra est comme suit.
1 octet pour type d'image/0=raw, 1=JPEG/
Alors ce qui suit 4 octet pour la taille de l'image
Puis après ça sera n octet avec l'ordre suivant
2 largeur d'octet, 2 hauteur des octets, 1 octet pour B, 1 pour R octet 1 Octet pour g

Par conséquent, j'essaie d'obtenir des données et de les convertir à l'image à l'aide du code suivant:


#! /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`


Mais chaque fois que je lance le code, cela obtient toujours une telle erreur


"Value error not enough Image Data"


Et si vous changez


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


à


img = Image.fromstring/'BRG', /1280, 720/, imageData, 'raw'/


Je reçois cette erreur:


Value error: Unrecognized mode,


Est-ce que quelqu'un sait comment résoudre un tel problème?
Invité:

Agathe

Confirmation de:

Il est préférable de déboguer ces problèmes lorsque et du code du serveur et que le client est entièrement donné. /mais simplifié pour montrer juste le problème/.

Vous trouverez donc ci-dessous un client très simple basé sur votre code source et votre description. Notez que
image_type

Non utilisé, il n'existe que parce que vous avez mentionné que vous voulez distinction entre JPEG et RAW. Je suppose toujours que les données obtenues - Ceci est la donnée RGB, Vous pouvez les adapter à votre vrai problème. La principale différence ici est d'utiliser
struct

, Quelle est la méthode standard d'emballage des données dans un format général de transmission sur le réseau et d'éviter les problèmes liés à la commande d'octets. Ce code s'attend également à ce que la largeur et la hauteur de l'image. /qui n'étaient pas dans votre code/, Par conséquent, vous pouvez restaurer l'image dans le client.


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'/


Étant donné que le serveur n'a pas été activé, vous trouverez un exemple simple, qui respecte le protocole décrit. Je ne me suis pas dérangé en train de vérifier l'exhaustivité des données reçues sur le serveur. Notez également que ce serveur ne sert qu'une seule image spécifiée sur l'invite de commande lorsqu'elle commence. Encore une fois, adaptez votre problème. Notez également que je n'envoie pas le mode image, qui peut être un problème dans la demande réelle.


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//


Remarque surélevée qui n'est pas utilisée
__len__

, juste en raison du fait qu'il s'agit d'une méthode spéciale dans Python, qui s'appelle par lui-même
len

. Si vous n'avez pas de bonnes raisons d'utiliser des méthodes spéciales, ne le faites pas.

Giselle

Confirmation de:

Vous avez mentionné l'utilisation du serveur d'images de USARSim. Voici le code que j'utilise pour obtenir des images de USARSim /version UT2004/:


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/

Pour répondre aux questions, connectez-vous ou registre