Openseadragon: Change TileSource, clear cache and redraw

Created on 25 Feb 2016  路  5Comments  路  Source: openseadragon/openseadragon

Hi,

I'm using OSD with custom tile source, and through params after images src I send additional params om image:
for example: .....jpg?param1=value&param2=value

Can you show me the best way to clear OSD cache and redraw it with new tileSorce params?

question

All 5 comments

viewer.world.resetItems() clears all of the current tiles and sets it to reload.

Hi

Thanks. But after this action world update and receive images on old url.
I'm getting images by new url only if I changed zoom

Can you help me to solve problem with old image url

      var getTileUrl = viewer.source.getTileUrl,
          stamp = new Date().getTime();

      viewer.source.getTileUrl = function() {
        return getTileUrl.apply(this, arguments) + "?v=" + stamp;
      };

      viewer.world.resetItems();
      viewer.imageLoader.clear();
      viewer.world.update();

Hmm, in that case you're probably better off removing the tiledImage and replacing it with a new copy, like so:

var oldImage = viewer.world.getItemAt(0);
var oldBounds = oldImage.getBounds();
var oldSource = oldImage.source;

// Modify tile source as needed

viewer.addTiledImage({
    tileSource: oldSource,
    x: oldBounds.x,
    y: oldBounds.y,
    width: oldBounds.width, // It'll do height automatically based on aspect ratio
    success: function() {
        viewer.world.removeItem(oldImage);
    }
});

Ian,

Thanks a lot. You make me happy )
Best regards

I would like to share a much faster way of doing this. I was struggling with a similar scenario: the user has direct control on values that control how the tiles are being drawn. Going every time to the server for the original images took a bit of time, and attached on a slider and updating onchange it became pretty cumbersome. In my case, it made the app completely useless.

You can instead remember a timestamp when last the tile was drawn:

...addHandler( 'tile-loaded', function(e) {
                ... //draw first tile as seen fit from e.image data, and set appropriately e.tile.context2D so that it will be used

                // Save the original image for furture use
                e.tile.origData = e.image;
                // Note when the tile was last rendered and re-draw if too old
                e.tile.lastDrawnTStamp= Date.now();
        }

so once a tile is loaded, you first draw the output tile based on default parameters, and then you redraw any tile if and only if it needs to be redrawn, as so:

... addHandler('tile-drawing', function(e) {
            if (e.tile.lastDrawnTStamp <= this.upToDateTStamp) {

                e.tile.lastDrawnTStamp= this.upToDateTStamp + 1;

                // Render an image as seen fit using new parameters, use e.tile.origData as the original image
                output = drawfrom(e.tile.origData, ...)

                // Clear the tile canvas in case the layer uses transparency, or don't otherwise
                e.rendered.clearRect(0, 0, e.tile.sourceBounds.width, e.tile.sourceBounds.height);
                // Give OSD new image data 
                e.rendered.drawImage(output, 0, 0, e.tile.sourceBounds.width, e.tile.sourceBounds.height);
            }
        }

and finally, to reset the canvas do


//we will be resetting layerIndex - index of tile source
var imageTile = world.getItemAt(layerIndex);

// Raise tstamp to force redraw
this.upToDateTStamp = Date.now();

//force clear context, pretty dirty to touch private attributes but sorry, calling public member functions does not work, maybe there is better way to do this, you can let me know :)
imageTile._drawer.context.clearRect(0, 0, imageTile._drawer.context.canvas.width, imageTile._drawer.context.canvas.height);

//reqest draw event
world.draw();
Was this page helpful?
0 / 5 - 0 ratings