首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在源于GoCV的Mat数据类型的html中显示图像

如何在源于GoCV的Mat数据类型的html中显示图像
EN

Stack Overflow用户
提问于 2021-10-29 05:06:08
回答 1查看 101关注 0票数 0

我想实现两件事,但现在我不能实现其中的一件。我用main.go做了一个WebSocket服务器,然后用vscode的实时服务器打开了index.html。在html页面上,当我单击"拍照“按钮时,我会调用服务器运行GoCV来使用我的笔记本网络摄像头进行自拍。到目前为止,一切都实现了。最后,我需要将自拍数据传递到html页面并呈现,我尝试将img转换为[]字节,如"img.ToBytes()“,然后传递给golang代码中的websocket,我将该二进制大对象转换为objectURL,然后传递给html中的标记,然后页面只显示一个没有图像的图像图标。我不知道如何解决这个问题。可能数据格式不合法,如何正确操作?

main.go

代码语言:javascript
复制
package main

import (
    "fmt"
    "log"
    "net/http"
    "time"

    "github.com/gorilla/websocket"
    "gocv.io/x/gocv"
)

var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

func homePage(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Home Page")
}

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 err := conn.WriteMessage(messageType, p); 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
            }
            fmt.Println("1")
            fmt.Println("2")
            img := gocv.NewMat()
            fmt.Println("3")

            if ok := webcam.Read(&img); !ok {
                fmt.Printf("Device closed: %v\n", 0)
                return
            }
            fmt.Println("4")

            Img = img
            fmt.Println("5")

            webcam.Close()

            fmt.Println("什麼都關了")

            //傳字
            conn.SetWriteDeadline(time.Now().Add(1000000000))

            w, err := conn.NextWriter(websocket.BinaryMessage)
            if err != nil {
                return
            }

            w.Write(img.ToBytes())

            if err := w.Close(); err != nil {
                return
            }
        }
        if string(p) == "someone is going to save the selfie" {
            fmt.Println("要存照片囉!!")
            gocv.IMWrite("selfie.jpg", Img)
        }
    }
}

func wsEndpoint(w http.ResponseWriter, r *http.Request) {
    upgrader.CheckOrigin = func(r *http.Request) bool { return true }

    // upgrade this connection to a WebSocket
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
    }
    log.Println("客戶端連接")

    reader(ws)
}

func setupRoutes() {
    http.HandleFunc("/", homePage)
    http.HandleFunc("/ws", wsEndpoint)
}

func main() {
    fmt.Println("伺服器開啟")
    setupRoutes()
    log.Fatal(http.ListenAndServe(":8080", nil))
}

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>GoCV作業延伸</title>
  </head>
  <body>
    <h2>GoCV作業延伸</h2>
    <div>
      <button id="capture" onclick="captureHandler();">拍照</button>
      <button id="save" onclick="saveHandler();">儲存</button>
    </div>
    <div><img id="img" /></div>
    <div class="column">
      <label for="upload" class="button file-label">Select Image</label>
      <input id="upload" class="hidden" type="file" accept="image/*" />
    </div>
    <div class="column">
      <img id="upload-image" />
    </div>
    <script>
      let socket = new WebSocket("ws://127.0.0.1:8080/ws");
      console.log("Attempting Connection...");

      socket.onopen = (capture) => {
        console.log("Successfully Connected");
        socket.send("Hi From the Client!");
      };

      socket.onclose = (event) => {
        console.log("Socket Closed Connection: ", event);
        socket.send("Client Closed!");
      };
      //?????????????????????????????????????????????????????????????????
      const uploadButton = document.getElementById("upload");

      const imgDOM = document.getElementById("upload-image");
      function createImageFromFile(img, file) {
        return new Promise((resolve, reject) => {
          console.log(URL.createObjectURL(file));
          img.src = URL.createObjectURL(file);
          img.onload = () => {
            URL.revokeObjectURL(img.src);
            resolve(img);
          };
          img.onerror = () => reject("Failure to load image.");
        });
      }

      function getFileBase64Encode(blob) {
        return new Promise((resolve, reject) => {
          const reader = new FileReader();

          reader.readAsDataURL(blob);
          reader.onload = () => resolve(reader.result);
          reader.onerror = (error) => reject(error);
        });
      }

      function handleFiles() {
        console.log(this);
        const fileList = this.files;
        console.log(fileList);
        const [file] = fileList;
        console.log(file);
        const p1 = createImageFromFile(imgDOM, file);
        const p2 = getFileBase64Encode(file);
        console.log(p1);
        Promise.all([p1, p2]).then((result) => {
          const [img, b64] = result;
        });
      }

      uploadButton.addEventListener("change", handleFiles, false);
      //?????????????????????????????????????????????????????????????????
      let capture = document.getElementById("capture");
      let imgdom = document.getElementById("img");
      socket.onmessage = (e) => {
        console.log(e);
        console.log(e.data);
        let blob = e.data;
        img.src = URL.createObjectURL(blob);

        function createImageFromBlob(img, blob) {
          return new Promise((resolve, reject) => {
            console.log(blob);
            console.log(URL.createObjectURL(blob));
            img.src = URL.createObjectURL(blob);
            img.onload = () => {
              URL.revokeObjectURL(img.src);
              resolve(img);
            };
            img.onerror = () => reject("Failure to load image.");
          });
        }

        function handleBlobs() {
          console.log(blob);
          createImageFromBlob(imgdom, blob);
        }
        capture.addEventListener("click", handleBlobs, false);
      };

      socket.onerror = (error) => {
        console.log("Socket Error: ", error);
      };
      function captureHandler() {
        socket.send("someone is going to take a selfie");
      }
      function saveHandler() {
        socket.send("someone is going to save the selfie");
      }
    </script>
  </body>
</html>
EN

回答 1

Stack Overflow用户

发布于 2021-11-01 04:34:37

我解决了这个问题,只需将图像编码到内存缓冲区,然后在传递之前将其转换为字节数组。这些操作将图像大小从2764800 (=1920x1440)字节压缩到大约50000字节。

替换

w.Write(img.ToBytes())

通过

buf, _ := gocv.IMEncode(".jpg", img)

w.Write(buf.GetBytes())

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69763884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档