You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IoT项目问题:树莓派Picam照片实时显示至000webhost网页遇Pubnub限制

解决树莓派Picam实时图传Pubnub大小限制的方案

我之前做树莓派IoT实时监控项目时,刚好碰到过Pubnub单条消息35KB限制的问题,给你几个亲测有效的解决思路:

方案1:分片传输Base64数据

既然单条消息放不下整图的Base64,那就把数据拆成多个符合大小限制的分片,前端收到所有分片后再重组解码。

树莓派端Python代码示例

import base64
from pubnub.pubnub import PubNub, PublishResult
from pubnub.config import PNConfiguration

# 初始化Pubnub(替换成你的密钥)
pnconfig = PNConfiguration()
pnconfig.subscribe_key = "YOUR_SUBSCRIBE_KEY"
pnconfig.publish_key = "YOUR_PUBLISH_KEY"
pubnub = PubNub(pnconfig)

def split_base64(b64_str, chunk_size=30*1024):  # 留5KB余量避免超限制
    return [b64_str[i:i+chunk_size] for i in range(0, len(b64_str), chunk_size)]

# 读取并转换图片为Base64
with open("/home/pi/picam_photo.jpg", "rb") as f:
    img_bytes = f.read()
    img_b64 = base64.b64encode(img_bytes).decode("utf-8")

# 拆分分片并发布
chunks = split_base64(img_b64)
total_chunks = len(chunks)
for idx, chunk in enumerate(chunks):
    pubnub.publish().channel("picam-stream").message({
        "type": "image_chunk",
        "chunk_idx": idx,
        "total_chunks": total_chunks,
        "data": chunk
    }).sync()

前端JavaScript代码示例

const pubnub = new PubNub({
    subscribeKey: "YOUR_SUBSCRIBE_KEY",
    publishKey: "YOUR_PUBLISH_KEY"
});

let imageChunks = {};
let totalChunks = 0;

pubnub.subscribe({ channels: ["picam-stream"] });

pubnub.addListener({
    message: function(m) {
        const msg = m.message;
        if (msg.type === "image_chunk") {
            imageChunks[msg.chunk_idx] = msg.data;
            totalChunks = msg.total_chunks;
            
            // 检查是否所有分片都已收到
            if (Object.keys(imageChunks).length === totalChunks) {
                // 重组Base64字符串
                const fullB64 = Object.values(imageChunks).join("");
                // 更新图片显示
                document.getElementById("picam-image").src = `data:image/jpeg;base64,${fullB64}`;
                // 重置分片存储
                imageChunks = {};
                totalChunks = 0;
            }
        }
    }
});

注意:可以加个超时机制,如果超过5秒没收到所有分片,就触发重传请求(树莓派端需要监听这个请求),避免丢包导致卡住。

方案2:压缩图片到Pubnub限制内

如果对画质要求不是特别高,直接在树莓派端压缩图片,把Base64后的大小控制在35KB以内是最省事的方法。

树莓派端Python压缩示例(用PIL库)

from PIL import Image
import base64

# 打开Picam拍摄的图片
img = Image.open("/home/pi/picam_photo.jpg")

# 压缩:调整分辨率+降低质量
img = img.resize((640, 480))  # 缩小分辨率
img.save("/tmp/compressed_photo.jpg", quality=50, format="JPEG")  # 降低JPG质量

# 转Base64并发布
with open("/tmp/compressed_photo.jpg", "rb") as f:
    img_b64 = base64.b64encode(f.read()).decode("utf-8")
# 这里直接用你原来的Pubnub发布代码即可

如果用WebP格式,同样质量下体积比JPG小30%-50%,可以试试img.save("/tmp/compressed_photo.webp", quality=50, format="WEBP"),前端直接支持WebP图片。

方案3:替换为MQTT+HTTP文件上传(更稳定的长期方案)

如果Pubnub的限制实在束缚住了,换成MQTT传图片URL,树莓派直接把图片上传到000webhost的主机上,前端加载URL显示,这是工业级实时监控常用的思路。

步骤1:树莓派端上传图片到000webhost

假设你的000webhost主机有一个PHP接口upload.php(放在网站根目录):

<?php
$target_dir = "uploads/";
$target_file = $target_dir . uniqid() . ".jpg";
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
    echo $target_file; // 返回图片的相对URL
} else {
    echo "error";
}
?>

树莓派端Python上传代码:

import requests
import paho.mqtt.client as mqtt

# 上传图片到000webhost
url = "https://your-000webhost-domain.com/upload.php"
files = {"file": open("/home/pi/picam_photo.jpg", "rb")}
response = requests.post(url, files=files)
img_url = response.text

# MQTT发布图片URL(用本地或公共MQTT broker,比如Mosquitto)
client = mqtt.Client()
client.connect("mqtt-broker-address", 1883, 60)
client.publish("picam/stream", img_url)
client.disconnect()

步骤2:前端监听MQTT并显示图片

const client = new Paho.MQTT.Client("mqtt-broker-address", 1883, "web-client-id");

client.onMessageArrived = function(message) {
    const imgUrl = message.payloadString;
    document.getElementById("picam-image").src = `https://your-000webhost-domain.com/${imgUrl}`;
};

client.connect({ onSuccess: function() {
    client.subscribe("picam/stream");
}});

注意:000webhost的免费主机可能有文件大小和流量限制,记得定期清理旧图片。


内容的提问来源于stack exchange,提问作者Nono

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:12:20