GWT:循环加载图像

时间:2013-04-18 12:02:57

标签: image gwt reload

我尝试实现一种继承简单JPEG文件的Videostream。 在我的服务器上,外部摄像头正在循环创建JPEG。 我只想在GWT应用程序中包含此图片。

我通过计时器重新加载图片的第一个想法非常简单但不太好:客户端为每个重新加载周期打开一个连接,并且图片闪烁(至少在Firefox中)。

我怎样才能解决这些问题?我在考虑像“Web-Sockets”这样的东西,但我真的不知道该怎么做。 我想避免每次重新加载一个连接。我的想法是像开放式连接那样只提供客户要求的新图片。

交换图片时如何避免闪烁?

欢迎任何想法!

此致,VanDahlen

1 个答案:

答案 0 :(得分:0)

避免闪烁的解决方案是将两个图像绝对放置在同一位置。计时器将在每个帧中交替加载一个或另一个。为每个图像设置一个load处理程序,以便在加载图像时更改z-index并重新启动计时器。

向图片网址添加额外参数,使浏览器每次都要求服务器绕过其缓存。

如果帧之间的时间很短,通常在服务器中正确配置keep-alive时,浏览器将重新使用相同的连接。它通常启用的典型值为5-15秒,您可以增加,所以如果您的.jpg图像使用此周期更新,您不必担心并寻找更好的解决方案。

我提出了基于这些想法的UI解决方案。但是如果你使用websocket / comet机制为你提供base64格式的最后一个.jpg文件(只需用返回的值更改url),它也会工作。

GWT代码:

public void onModuleLoad() {

  final Image i1 = new Image();
  i1.setWidth("400px");

  final Image i2 = new Image();
  i2.setWidth("400px");

  AbsolutePanel panel = new AbsolutePanel();
  panel.add(i1, 0, 0);
  panel.add(i2, 0, 0);
  panel.setSize("600px", "400px");

  RootPanel.get().add(panel);

  // You could change this by base64 data if you use comet/websockets
  String url = "my_image_url.jpg?";

  final Timer loadNext = new Timer() {
    boolean b;
    int c;
    public void run() {
      // the counter parameter forces to load the next frame instead of using cache
      if (b  = !b) {
        i1.setUrl(url + c++);
      } else {
        i2.setUrl(url + c++);
      }
    }
  };

  i1.addLoadHandler(new LoadHandler() {
    public void onLoad(LoadEvent event) {
      i1.getElement().getStyle().setZIndex(1);
      i2.getElement().getStyle().setZIndex(0);
      loadNext.schedule(1000);
    }
  });

  i2.addLoadHandler(new LoadHandler() {
    public void onLoad(LoadEvent event) {
      i1.getElement().getStyle().setZIndex(0);
      i2.getElement().getStyle().setZIndex(1);
      loadNext.schedule(1000);
    }
  });

  loadNext.schedule(1000);
 }

如果您想使用gwtquery,代码显然会更小:

  // You could change this by base64 data if you use comet/websockets
  final String url = "my_image_url.jpg?";

  final GQuery images = $("<img/><img/>").appendTo(document);
  images.css($$("position: fixed, top: 10px, left: 600px, width: 400px"));

  final Timer timer = new Timer() {
    int c;
    public void run() {
      images.eq(c%2).attr("src", url + c++);
    }
  };

  images.bind("load", new Function(){
    public void f() {
      $(this).css($$("z-index: 1")).siblings("img").css($$("z-index: 0"));
      timer.schedule(1000);
    }
  });

  timer.schedule(1000);