使用 Micropython 将图像二进制数据存储到 MongoDB 中的 HTTP 请求中
首先
这次,我想要将ESP32的图像文件存储到MongoDB中,但由于我是初学者,所以在实现过程中遇到了一些困难,因此我想把这篇文章当作备忘录或知识整理来写。我不知道是否有人会做这种事情,所以不确定是否有需要…
我想要做的事情

ESP32(发送端)向ESP32(接收端)发送图像的二进制数据,并且ESP32(接收端)希望使用HTTP请求将图像数据发送到运行在VM上的MongoDB。由于不确定能否将图像直接存储到MongoDB中,所以本次将其转换为二进制并保存为文本。
ESP32之间的交流是通过套接字通信实现的。
执行
在这里,我们将省略有关创建套接字等部分的描述。这里仅描述图像数据传输的前处理和HTTP请求的部分。
在ESP32(发信端)的处理中
def sending():
global port
global socket_to_KH
global address
global message
global s
while True:
connection, client = s.accept()
with open('material.jpeg', 'rb') as image_file:
image_data = image_file.read()
try:
print(f'----Client {client} connected----')
image_size = len(image_data)
send_count = (image_size // buffer_size) + 1
connection.send(str(send_count).encode())
for i in range(send_count):
start = i * buffer_size
end = min((i + 1) * buffer_size, image_size)
chunk = image_data[start:end]
connection.sendall(chunk)
print('Number of chunks:', send_count)
utime.sleep(2)
finally:
connection.close()
print('connection is closed')
break
因为超过缓冲区大小时,在套接字通信中进行发送将会失败,所以我们需要使用缓冲区大小来分割发送文件的大小。通过将文件一次性分割成块,并使用sendall()函数来发送,可以成功地进行发送。
ESP32(作为接收方)的处理。
def receiving():
global host
global port
global socket_to_KM
global address
global message
host = wifi.ifconfig()[2]
try:
sendSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
red.on()
sendSocket.connect((host,port))
red.off()
sendSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
data = sendSocket.recv(buffer_size)
send_count = int(data.decode())
print('Number of chunks:', send_count)
image_data = b""
for i in range(send_count):
chunk = sendSocket.recv(buffer_size)
image_data += chunk
with open('received_image.jpg', 'wb') as image_file:
image_file.write(image_data)
print("Image received and saved as 'received_image.jpg'.")
print(f'received message: {message}')
sendSocket.close()
except Exception as e:
print(e)
pass
我会将接收到的分块数据逐个放入image_data中。这样,就可以在ESP32之间进行图像数据的交互了。
接下来,将通过HTTP请求将数据存储在MongoDB中。
def mkb():
with open('received_image.jpg', 'rb') as image_file:
image_data = image_file.read()
return image_data
将二进制数据转化为字符串。
def toServer():
image_data = mkb()
url = 'http://192.168.***.***:5000/data'
files = {'image':('received_image.jpg',image_data)}
print(files)
response = urequests.post(url, json=files)
if response.status_code == 201:
print('Data saved successfully')
else:
print('Failed to save data.')
response.close()
我们将二进制数据称为image_data。
url指定了mongoDB的数据集合。
files是要发送的图像数据的二进制数据。
由于是使用MicroPython,所以我会使用urequests进行POST请求。我会接收并检查响应状态码。
最后。
这样,我们就可以通过HTTP请求将ESP32上的数据存储到MongoDB中了。虽然这次我们要发送图像数据,但是如果尺寸过大,即使进行分块传输,也可能无法成功发送。