Python 将图像发布到Django REST API

Python 将图像发布到Django REST API,python,django,numpy,post,encoding,Python,Django,Numpy,Post,Encoding,我有一个Django项目,它接收图像,处理图像并返回响应。我正在编写一个脚本来测试我的API,但是客户端发送的字节与服务器接收的字节不同 客户端代码: # client.py from urllib.parse import urlencode from urllib.request import Request, urlopen import cv2 img = cv2.imread(image_file) data = {'image': img.tobytes(), 'shape': i

我有一个Django项目,它接收图像,处理图像并返回响应。我正在编写一个脚本来测试我的API,但是客户端发送的字节与服务器接收的字节不同

客户端代码:

# client.py
from urllib.parse import urlencode
from urllib.request import Request, urlopen
import cv2

img = cv2.imread(image_file)
data = {'image': img.tobytes(), 'shape': img.shape}
data = urlencode(data).encode("utf-8")
req = Request(service_url, data)
response = urlopen(req)
print(response.read().decode('utf-8'))
# client.py
import base64
from urllib.parse import urlencode
from urllib.request import Request, urlopen
import cv2

img = cv2.imread(image_file)
img_b64 = base64.b64encode(img)
data = {'image': img_b64, 'shape': img.shape}
data = urlencode(data).encode("utf-8")
req = Request(service_url, data)
response = urlopen(req)
print(response.read().decode('utf-8'))
视图代码:

# service/app/views.py
import ast
import numpy as np
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def process_image(request):
    if request.method == 'POST':
        # Converts string to tuple
        shape = ast.literal_eval(request.POST.get('shape'))
        img_bytes = request.POST.get('image')
        # Reconstruct the image
        img = np.fromstring(img_bytes, dtype=np.uint8).reshape(shape)
        # Process image
        return JsonResponse({'result': 'Hello'})
# service/app/views.py
import ast
import base64
import numpy as np
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def process_image(request):
    if request.method == 'POST':
        shape = ast.literal_eval(request.POST.get('shape'))
        buffer = base64.b64decode(request.POST.get('image'))
        # Reconstruct the image
        img = np.frombuffer(buffer, dtype=np.uint8).reshape(shape)
        # Process image
        return JsonResponse({'result': 'Hello'})
当我运行客户端代码时,我得到ValueError:新数组的总大小必须保持不变。我使用8x8 RGB图像进行了以下检查:

# client.py
>> print(img.shape)
(8, 8, 3)
>> print(img.dtype)
uint8
>> print(len(img.tobytes()))
192

# service/app/views.py
>> print(shape)
(8, 8, 3)
>> print(len(img_bytes))
187
形状字段正常,但图像字段的大小不同。由于图像很小,我打印了来自客户端和服务器的字节,但没有得到相同的结果。我认为这是一个编码问题

我想以字节的形式发送图像,因为我认为这是一种发送此类数据的紧凑方式。如果有人知道通过HTTP发送图像的更好方法,请告诉我


谢谢

受约翰·莫里斯评论的启发,我在帖子中找到了我问题的答案。如果有人有同样的疑问,以下是解决方案:

客户端代码:

# client.py
from urllib.parse import urlencode
from urllib.request import Request, urlopen
import cv2

img = cv2.imread(image_file)
data = {'image': img.tobytes(), 'shape': img.shape}
data = urlencode(data).encode("utf-8")
req = Request(service_url, data)
response = urlopen(req)
print(response.read().decode('utf-8'))
# client.py
import base64
from urllib.parse import urlencode
from urllib.request import Request, urlopen
import cv2

img = cv2.imread(image_file)
img_b64 = base64.b64encode(img)
data = {'image': img_b64, 'shape': img.shape}
data = urlencode(data).encode("utf-8")
req = Request(service_url, data)
response = urlopen(req)
print(response.read().decode('utf-8'))
视图代码:

# service/app/views.py
import ast
import numpy as np
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def process_image(request):
    if request.method == 'POST':
        # Converts string to tuple
        shape = ast.literal_eval(request.POST.get('shape'))
        img_bytes = request.POST.get('image')
        # Reconstruct the image
        img = np.fromstring(img_bytes, dtype=np.uint8).reshape(shape)
        # Process image
        return JsonResponse({'result': 'Hello'})
# service/app/views.py
import ast
import base64
import numpy as np
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def process_image(request):
    if request.method == 'POST':
        shape = ast.literal_eval(request.POST.get('shape'))
        buffer = base64.b64decode(request.POST.get('image'))
        # Reconstruct the image
        img = np.frombuffer(buffer, dtype=np.uint8).reshape(shape)
        # Process image
        return JsonResponse({'result': 'Hello'})

谢谢大家!

我不明白literal_eval在这里的意义。@DanielRoseman literal_eval将形状从字符串转换为元组。绝不是像你想要的那样紧凑,我有一个rest服务,我只是在发布之前对图像进行base64编码,然后在服务器上解码。我认为您的问题可能是将原始字节放入JSON请求中。我不认为可以将原始字节放入JSON。例如,引号字符的字节将关闭值字符串。谢谢@JohnMorris!