簡體   English   中英

如何使用 Java / Javascript 通過 Web Socket 將圖像從服務器發送到客戶端?

[英]How to send an image from server to client with Web Socket using Java / Javascript?

我正在開發一個應用程序,它使用 Web Socket 從服務器向客戶端發送圖像,似乎數據已發送,但圖像未顯示在 html 頁面中。

我在網上搜索了解決方案,包括在 WebSocket 中接收 Blob 並在畫布中呈現為圖像以及如何從 Java websocket 服務器發送圖像以在 HTML5 畫布中使用?

連接已正確建立,我什至可以在 html 畫布中繪制一個矩形,但到目前為止我嘗試過的任何內容都無法解決我的問題 [通過圖像發送],我的代碼如下所示:

服務器端 :

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.Random;
import javax.imageio.ImageIO;

public class Image_Getter
{
    int W,H,g,b;
  BufferedImage Buffered_Image = null;
    String Image_Path="C:/Dir_WebSocket_Jetty/demo.png";

    public Image_Getter(int W,int H)
  {
        this.W=W;
        this.H=H;
    Buffered_Image = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);
  }

  BufferedImage getAnImage()
  {
    try
        {
//          image = ImageIO.read(new File("image.jpg"));
            int x_1=getRandomNumber(0,W/2),x_2=getRandomNumber(W/2,W),r=getRandomNumber(0,230),g=getRandomNumber(60,230),b=getRandomNumber(90,250);
            for (int x=0;x<W;x++)
                if (x < x_1 || x_2 < x) for (int y=0;y<H;y++)   setColor(x,y,getRandomNumber(0,253),getRandomNumber(0,253),getRandomNumber(0,253),getRandomNumber(0,253));
                else for (int y=0;y<H;y++) setColor(x,y,r,g,b,253);
            ImageIO.write(Buffered_Image,"png",new File(Image_Path));
        }
        catch (Exception e) {   System.out.println("Error : " + e.getMessage());    }
    return Buffered_Image;
  }

    void setColor(int x,int y,int r,int g,int b,int a)   // r,g,b,a [ alpha (transparency) ] : 0 .. 255
    {
        int col = (a << 24) | (r << 16) | (g << 8) | b;
        Buffered_Image.setRGB(x,y,col);
    }

  int getRandomNumber(int min,int max)
  {
    int range=max-min+1,rand=(int)(Math.random()*range)+min; 
    return rand;
  }

  private static void out(String message) { System.out.print(message); }
  private static void Out(String message) { System.out.println(message); }
}

================================================== ============

    Session s = sMap.get(key);

    if (s.isOpen())
    {
      BufferedImage image = image_getter.getAnImage();
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ImageIO.write(image,"jpg",baos);
      byte[] byteArray = baos.toByteArray();
   // s.getBasicRemote().sendText();  // connection.sendMessage(byteArray, 0, byteArray.length);

      String base64String = Base64.encode(byteArray);

      s.getBasicRemote().sendText(base64String);
   // s.getBasicRemote().sendBinary(Base64.encode(byteArray));
   // s.getBasicRemote().sendBinary(ByteBuffer.wrap(byteArray));

    }

客戶端javascript:

class WebSocketImageClient
{
  constructor(protocol, hostname, port, endpoint)
  {
    this.webSocket = null;
    this.protocol = protocol;
    this.hostname = hostname;
    this.port = port;
    this.endpoint = endpoint;
  }

  getServerUrl() { return this.protocol + "://" + this.hostname + ":" + this.port + this.endpoint; }

  present() { return "Image Url = [ <font color=#0022CC>" + this.getServerUrl() + "</font> ]"; }

  connect()
  {
    var canvas = document.getElementById("imageCanvas");
    var context = canvas.getContext("2d");

    try
    {
      this.webSocket = new WebSocket(this.getServerUrl());
//      this.websocket.binaryType = "arraybuffer";

      // Implement WebSocket event handlers!
      this.webSocket.onopen = function (event)
      {
        console.log('onopen :: ' + JSON.stringify(event, null, 4));
      };

      this.webSocket.onmessage = function (event)
      {
        var msg = event.data;
        console.log('onmessage ::  ' + JSON.stringify(msg, null, 4));
//        var imageoutput = document.getElementById("imageCanvas");
/*
          var image = new Image();
          image.src = msg;
//          image.data = msg;
           image.onload = function() {
          context.drawImage(image, 0, 0);
          };
*/
        if (msg)
        {

          if (msg instanceof Blob)
          {
            var blob = msg;

            var bytes = new Uint8Array(blob);
            var image = context.createImageData(canvas.width, canvas.height);
            for (var i = 0; i < bytes.length; i++)
            {
              image.data[i] = bytes[i];
            }
//            alert("image = "+image);
            context.drawImage(image, 0, 0);
          }

        }
//        context.fillStyle = "#0000DD";
//        context.fillRect(160, 60, 36, 36);                // This can draw a rectangle
//        imageoutput.innerHTML = msg;

      };
      this.webSocket.onclose = function (event)
      {
        console.log('onclose :: ' + JSON.stringify(event, null, 4));
      };
      this.webSocket.onerror = function (event)
      {
        console.log('onerror :: ' + JSON.stringify(event, null, 4));
      };

    }
    catch (exception)
    {
      console.error(exception);
    }
  }

  getStatus()
  {
    return this.webSocket.readyState;
  }

  send(message)
  {
    if (this.webSocket.readyState == WebSocket.OPEN)
    {
      this.webSocket.send(message);
    }
    else
    {
      console.error('webSocket is not open. readyState=' + this.webSocket.readyState);
    }
  }

  disconnect()
  {
    if (this.webSocket.readyState == WebSocket.OPEN)
    {
      this.webSocket.close();
    }
    else
    {
      console.error('webSocket is not open. readyState=' + this.webSocket.readyState);
    }
  }
}

沒有錯誤消息,它看起來像這樣:

在此處輸入圖片說明

似乎有很多數據被發送到瀏覽器,我可以從開發者工具中看到,它看起來像這樣:

在此處輸入圖片說明

如果我取消注釋繪制矩形的線條,它看起來像這樣:

在此處輸入圖片說明

我在服務器端生成的圖像如下所示:

在此處輸入圖片說明

那么,我需要做什么才能使圖像顯示在 html 頁面中?

在您的服務器代碼中,您將其作為 .jpg 發送,但在您的客戶端代碼中,您只是嘗試繪制它而不對其進行解碼。 而不是發送 .jpg,也許只發送您在 JS 中設置的顏色矩陣

現在我開始工作了,在服務器端,代碼如下所示:

for (String key : sMap.keySet())
{
  Session s = sMap.get(key);

  if (s.isOpen())
  {
    BufferedImage image = image_getter.getAnImage();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
//  ImageIO.write(image,"jpg",baos);
    ImageIO.write(image,"png",baos);
    byte[] byteArray = baos.toByteArray();
    s.getBasicRemote().sendObject(byteArray);       // Works on both Swing & browser client
  }
  else sMap.remove(key);
}

在瀏覽器客戶端,javascript 如下所示:

this.webSocket.onmessage = function (event)
{
  var msg = event.data;
  console.log('onmessage ::  ' + msg);                                   // [object Blob]

  var blobUrl = URL.createObjectURL(new Blob([msg]));
  var image = new Image();
  image.src = blobUrl;
// alert("blobUrl = "+blobUrl);                                           // blob:http://localhost:8080/cc3751d6-5b49-462d-8a6f-f2221c899abf
  image.onload = function() { context.drawImage(image, 0, 0); };
};

在 Swing 客戶端,java 代碼如下所示:

@OnWebSocketMessage
public void onMessage(InputStream is)
{
  try
  {
    if (imageLabel!=null)
    {
      BufferedImage img = ImageIO.read(is);
      imageLabel.setIcon(new ImageIcon(img));
    }
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM