使用 Micropython 将图像二进制数据存储到 MongoDB 中的 HTTP 请求中

首先

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

我想要做的事情

data_flow.png

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中了。虽然这次我们要发送图像数据,但是如果尺寸过大,即使进行分块传输,也可能无法成功发送。

广告
将在 10 秒后关闭
bannerAds