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

如何在HTML中展示通过WebSocket传输的GoCV Mat类型图片

问题原因

  1. 服务端直接发送的是GoCV Mat类型的原始像素数据,没有编码为浏览器可识别的JPG/PNG等标准图片格式,浏览器无法解析原始像素流为可显示的图片
  2. 前端代码存在变量引用错误、冗余事件绑定的逻辑问题,即使数据正确也无法正常渲染
  3. 服务端原有逻辑会先回显收到的文本消息,干扰后续二进制图片消息的处理

修复方案

1. Go服务端修改

  • 删掉无用的消息回写逻辑,避免文本消息干扰
  • 使用gocv.IMEncode将Mat编码为JPG格式的字节流再发送
  • 及时释放编码产生的缓存

修改后的reader函数核心代码:

func reader(conn *websocket.Conn) {
    Img := gocv.NewMat()
    for {
        // read in a message
        messageType, p, err := conn.ReadMessage()
        fmt.Println(string(p))
        if err != nil {
            log.Println(err)
            return
        }
        // 删掉原来的回写消息逻辑

        if string(p) == "someone is going to take a selfie" {
            webcam, err := gocv.OpenVideoCapture(0)
            if err != nil {
                fmt.Printf("Error opening video capture device: %v\n", 0)
                return
            }
            img := gocv.NewMat()
            if ok := webcam.Read(&img); !ok {
                fmt.Printf("Device closed: %v\n", 0)
                return
            }
            Img = img
            webcam.Close()

            conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
            w, err := conn.NextWriter(websocket.BinaryMessage)
            if err != nil {
                return
            }
            // 将Mat编码为JPG格式再发送
            buf, err := gocv.IMEncode(".jpg", img)
            if err != nil {
                log.Println(err)
                return
            }
            defer buf.Close()
            w.Write(buf.GetBytes())
            if err := w.Close(); err != nil {
                return
            }
        }
        if string(p) == "someone is going to save the selfie" {
            fmt.Println("要存照片囉!!")
            gocv.IMWrite("selfie.jpg", Img)
        }
    }
}

2. 前端页面修改

  • 删除onmessage回调内冗余的事件绑定逻辑,收到二进制消息直接渲染
  • 修复变量名错误,新增消息类型判断,只处理二进制图片消息
  • 增加内存释放逻辑,避免Blob URL占用内存

修改后的socket.onmessage代码:

let imgdom = document.getElementById("img");
socket.onmessage = (e) => {
  // 只处理二进制图片消息,文本消息直接打日志
  if (e.data instanceof Blob) {
    const blobUrl = URL.createObjectURL(e.data)
    imgdom.src = blobUrl
    // 图片加载完成后释放内存
    imgdom.onload = () => {
      URL.revokeObjectURL(blobUrl)
    }
    imgdom.onerror = () => {
      console.error("图片加载失败")
      URL.revokeObjectURL(blobUrl)
    }
  } else {
    console.log("收到文本消息:", e.data)
  }
};
// 删掉onmessage回调内原来的createImageFromBlob、handleBlobs、capture.addEventListener等冗余逻辑

修改完成后重新运行服务端,点击拍照按钮即可正常显示拍摄的图片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:48:03