openseadragon / openseadragon

An open-source, web-based viewer for zoomable images, implemented in pure JavaScript.
http://openseadragon.github.io/
BSD 3-Clause "New" or "Revised" License
3.04k stars 595 forks source link

Q: how to keep the zoom constant for a sequence of images? #1238

Closed lihan2016nju closed 6 years ago

lihan2016nju commented 7 years ago

i have a squence of images, i want if i zoom one of these images, the images after it can keep the zoom constant and fixed position? i know
sequenceMode: true, preserveViewport: true, can solve the priblem. But, i show different DZi images like belows

function change(){
 OpenSeadragon({    
     //$("#aa").mousedown(function(){ 
        //OpenSeadragon({   
              id: "openSeadragon1", //the div taht will be showed
              prefixUrl: "./images/",
              sequenceMode: true,
              preserveViewport:true,
              tileSources: [{
              Image: {
              xmlns:  "http://schemas.microsoft.com/deepzoom/2009",
              Url: src[i],
              Overlap: "1",
              TileSize: "256",
              Format : "png",
              Size:{
                 Height: "3635",
                 Width:  "13352"
                   }  
                     }
                     }]
              });
         }}
window.setInterval("change()",200)

so, the sequence mode does not work, is there other solution?

iangilman commented 7 years ago

Sure... create the viewer just once, and then just change the page in change. Something like so:

var tileSouces = [];
var i;
for (i = 0; i < src.length; i++) {
  tileSources.push({
    Image: {
      xmlns:  "http://schemas.microsoft.com/deepzoom/2009",
      Url: src[i],
      Overlap: "1",
      TileSize: "256",
      Format : "png",
      Size:{
         Height: "3635",
         Width:  "13352"
      }  
    }  
  });
}

var viewer =  OpenSeadragon({   
  id: "openSeadragon1", //the div taht will be showed
  prefixUrl: "./images/",
  sequenceMode: true,
  preserveViewport:true,
  tileSources: tileSources
});

i = 0;

function change(){
  i = (i + 1) % src.length;
  viewer.goToPage(i);
}

window.setInterval(change, 200);
lihan2016nju commented 7 years ago

cool! thx for your reply! it works! But, now i meet a new problem . when 'window.setInterval(change, 200); ' works, the picture always flashes with image switching. I think the reason is once the function belows is called, the picture will appear with flashes. OpenSeadragon({
id: "openSeadragon1", //the div taht will be showed prefixUrl: "./images/", sequenceMode: true, preserveViewport:true, tileSources: tileSources }); viewer.goToPage(i);

actually, i want to play the DZi images continuously, just like play a video. but now the problem of flickering pictures bothers me, how can i fix it?

iangilman commented 7 years ago

To avoid the flickering, you'll have to use the multi-image API rather than sequence mode. Here's an example: https://codepen.io/iangilman/pen/PjdyGv

lihan2016nju commented 7 years ago

thx again! sorry one more question. when i run the code, the screen (actually the video) is a bit shaking and fuzzy, especially zooming into a small area. I think the reason is the size (15499*4084) of my image is very large, and when i create the dzi image , i set the TileSize: "256" . so the the period of loading tiled image is time-consuming , which causes the shaking problem. Addtionally, because the shaking and fuzzy problem, i set the setTimeout {function(),80), the framerate is about 10fps, i want to increase the framerate to 30 fps, but the smaller of value "setTimeout " is , the more intense the video shakes. Looking forward to your reply soon! thx!

var num=0; var src=new Array(); for (num=0;num<100;num++){ src[num] = "./DZI/"+num+"_files/"; } var tileSources = []; var i; for (i = 0; i < src.length; i++) { tileSources.push({ Image: { xmlns: "http://schemas.microsoft.com/deepzoom/2009", Url: src[i], Overlap: "1", TileSize: "256", Format : "png", Size:{ Height: "4084", Width: "15499" }
}
}); } var viewer = OpenSeadragon({
id: "openSeadragon1", //the div taht will be showed prefixUrl: "./images/", tileSources: tileSources[0] }); index=1; function addFrame(){ var tileSource=tileSources[index]; index++; if(index>=tileSources.length){ index=0;} viewer.addTiledImage({ tileSource:tileSource, index:0, success: function(event) { var tiledImage = event.item;

  var handler = function(event) {
    if (event.tiledImage === tiledImage) {
      viewer.removeHandler('tile-drawn', handler);
      setTimeout(function() {
        viewer.world.removeItem(viewer.world.getItemAt(1));
        addFrame();            
      }, 80);
    }
  }
  viewer.addHandler('tile-drawn', handler);
   }

}); } viewer.addHandler('open', function() { addFrame(); });

lihan2016nju commented 7 years ago

Now, when i open the html page, the video is played automatically. how can i add the 'start' button and 'stop' button to control the video playing? I write the code like below, but it does not work.

...... function run(){ viewer.addHandler('open', function() { addFrame(); });}

iangilman commented 7 years ago

The shaking you're seeing is because the image hasn't fully loaded when you flip to it. To know when it's fully loaded, you'll have to use the fully-loaded-change event that's not yet released. You can get it by building from the master branch of this repository, or you can wait for the release (hopefully soon, see #1094).

To have a button start the animation, you'd just have the button call addFrame directly; don't put the viewer.addHandler in the button click handler.

To stop the animation, you'd want to set a flag, and addFrame can check that flag to see if it really should add another frame or not.

lihan2016nju commented 7 years ago

@iangilman thx! It seems that you can release the latest version this week. And this version will add fully-loaded-change event which addresses my shaking problem, right? If the fully-loaded-change really work, i have 200 frames, each frame is very large as i mentioned above, will the time of loading all the files be very long? Additionally, i try to use addTiledImage to preload all tile files , but it does not improve the slow loading phenomenon. It means i have to wait for a long time until all tiled images are loaded. Here is the link: Will the latest version be able to handle the two problems? Looking forward to your reply soon! thx again.

iangilman commented 7 years ago

Yes, we should revisit this after 2.3.0 is released.

That said, OSD is definitely not optimized for this kind of scenario. If you want to play video, you may be better off using a video format. Of course then you wouldn't get the zooming. Anyway, just be aware that you're on the cutting edge here.

I'll give some thought to pre-loading, but it may not be worth it. At any rate, let's see how far we can push it without having to pre-load.

lihan2016nju commented 7 years ago

Thanks a lot for your support! Sorry, i am not good at I/O event. I will wait for 2.3.0 version and do some improvement based on this. By the way, where will the 2.3.0 be released ? in the"issues"' or somewhere else? i'm afraid i will miss the date of 2.3.0.

iangilman commented 7 years ago

Sounds good. You can subscribe to https://github.com/openseadragon/openseadragon/issues/1094 for the release announcement. We'll also announce via Twitter:

https://twitter.com/openseadragon/

lihan2016nju commented 7 years ago

Sorry. Before 2.3.0 is released, i think is there something i can do to improve the problems above?

when i run the code, the screen (actually the video) is a bit shaking and fuzzy, especially zooming into a small area. http://cite.nju.edu.cn/testv9.html If i understand #1193 correctly, the updated tiledimage.js loadingCoverage loaded loading does not need to load too many files, so does that mean when i play multi-images continuously, the framerate will be higher? and the screen will be smoother when zooming into one area?

iangilman commented 7 years ago

Not really, unless you want to build master from this repository. At any rate, we're expecting to release tomorrow.

lihan2016nju commented 7 years ago

Great! Thanks for your reply!

lihan2016nju commented 7 years ago

@iangilman How to make fullt-loaded-changework? I edit my code below,but it does not work. And, if the image is fully loaded, will it take up too much time which leads to the discontinuous dsiplay? Here is the demo(http://cite.nju.edu.cn/testv9.html) The code: var viewer = OpenSeadragon({ id: "openSeadragon1", prefixUrl: "./2.3.0/images/", tileSources: tileSources[0], }); index=1; var flag=1; function addFrame(){ var tileSource=tileSources[index]; index++; if(index>=tileSources.length){ index=0;} if (flag){ viewer.addTiledImage({ tileSource:tileSource, index:0, success: function(event) { viewer.addHandler('fully-loaded-change', function(){ setTimeout(function() { viewer.world.removeItem(viewer.world.getItemAt(1)); addFrame(); }, 100); }) } }); } } Thx!

iangilman commented 7 years ago

Here's my updated demo using fully-loaded-change:

https://codepen.io/iangilman/pen/PjdyGv

Let me know if that helps!

lihan2016nju commented 7 years ago

Cool! The flickering problem has been fixed now. Even though the framerate can not reach video framerate because of the loading time, the result is still much better. Maybe it is the best result I can get.

iangilman commented 7 years ago

Yes, it may be the best we can do. One thing to try would be preloading all of the images before showing the image in the first place (showing a progress bar instead or something), but then the user will have a long time to wait in the beginning.

Beyond that, we'd probably have to invent some sort of streaming protocol for OSD, which would require a specialized server.