Как отправить изображение с сервера на клиент с помощью веб-сокета, используя Java / Javascript? - PullRequest
1 голос
/ 04 марта 2020

Я разрабатываю приложение, которое отправляет изображение с сервера на клиент с помощью Web Socket, похоже, данные были отправлены, но изображение не отображается на странице html.

I ' Мы искали в Интернете решения, включая Получение BLOB-объектов в WebSocket и рендеринг в виде изображений в Canvas и Как отправить изображение с сервера Java websocket для использования на HTML5 canvas?

Соединение установлено правильно, и я даже могу нарисовать прямоугольник на холсте 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);
    }
  }
}

Нет сообщения об ошибке, и оно выглядит так:

enter image description here

Кажется, много данных было отправлено в браузер Я могу видеть из инструмента разработчика, который выглядит следующим образом:

enter image description here

И если я откомментирую линии, чтобы нарисовать прямоугольник, это будет выглядеть так:

enter image description here

Изображение, сгенерированное мной на стороне сервера выглядит следующим образом:

enter image description here

Итак, что мне нужно сделать, чтобы изображение появилось на странице html?

Ответы [ 2 ]

1 голос
/ 04 марта 2020

В коде вашего сервера вы отправляете это как .jpg, но в коде вашего клиента вы просто пытаетесь нарисовать его, не расшифровывая. Вместо того, чтобы отправлять .jpg, возможно, отправьте только цветовую матрицу, когда вы устанавливаете ее в JS

0 голосов
/ 06 марта 2020

Теперь у меня все работает, на стороне сервера код выглядит так:

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();
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...