WebSocket可传输原始图片二进制数据,服务端用binary:true发送Buffer,客户端通过ArrayBuffer→Blob→createObjectURL绘制到Canvas,并支持帧流解析与像素级直传优化。

WebSocket 本身不直接支持图片文件或二进制流的“自动解析”,但可以通过 ArrayBuffer 或 Blob 传输原始图像数据(如 JPEG、PNG 的字节),再在前端用 Canvas 绘制。关键在于:服务端发送的是**未经 Base64 编码的原始二进制数据**,客户端接收后构造 Uint8Array → 转为 Blob → 创建 URL.createObjectURL() → 绘制到 Canvas。
服务端发送原始图片数据(以 Node.js + ws 为例)
不要转成 Base64,避免体积膨胀和额外解码开销。直接读取图片文件(或从摄像头/处理流程获取 Buffer),通过 WebSocket 二进制发送:
- 确保 WebSocket 服务端启用二进制支持(
ws库默认支持ArrayBuffer和Buffer) - 示例代码片段(服务端):
const fs = require('fs');
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
// 例如每次连接后发送一张 test.jpg
const imgBuffer = fs.readFileSync('./test.jpg');
ws.send(imgBuffer, { binary: true }); // 关键:binary: true
});
客户端接收并绘制到 Canvas
监听 message 事件,判断 event.data 类型为 ArrayBuffer,再转换为 Blob 并绘制:
- 检查
event.data instanceof ArrayBuffer,不是字符串或 Blob - 用
new Blob([event.data], { type: 'image/jpeg' })构造 Blob(注意 MIME 类型需与实际一致) - 调用
URL.createObjectURL(blob)获取临时 URL - 设置
img.src,并在img.onload中用ctx.drawImage(img, ...)渲染 - 记得每次绘制后
URL.revokeObjectURL(url)释放内存(尤其高频更新时)
优化实时性:支持连续帧(如视频流)
单张图只是起点。若需每秒多帧(如 15–30 FPS),建议:
立即学习“前端免费学习笔记(深入)”;
- 服务端按固定格式打包数据:例如前 4 字节为 uint32 表示长度,后续为 JPEG 数据 —— 避免粘包
- 客户端用
WebSocket.binaryType = 'arraybuffer'并自行拼接/分帧(使用Uint8Array和偏移解析) - Canvas 使用
requestAnimationFrame控制绘制节奏,避免阻塞主线程 - 可考虑 WebAssembly 解码(如使用 image-js)处理 YUV/RGB 原始帧,跳过 JPEG 编解码开销
替代方案:直接传输像素数组(更底层但更灵活)
若服务端能输出 RGBA 像素(如从 WebGL 截图或 OpenCV 处理),可传 Uint8ClampedArray:
- 服务端序列化为
Buffer.from(pixels)发送 - 客户端用
new Uint8ClampedArray(event.data)恢复像素 - 创建
ImageData对象:ctx.createImageData(width, height),再data.set(pixels) - 最后
ctx.putImageData(imageData, 0, 0)直接上屏 —— 零解码、零 DOM 图片对象,延迟最低



















