Avoid using data urls in ImageTileSource.

This commit is contained in:
Antoine Vandecreme 2015-11-02 19:42:14 -05:00
parent 14a83e1154
commit 37ca9235f8
3 changed files with 53 additions and 25 deletions

View File

@ -205,6 +205,20 @@
}
return url;
},
/**
* Retrieves a tile context 2D
* @function
* @param {Number} level Level of the tile
* @param {Number} x x coordinate of the tile
* @param {Number} y y coordinate of the tile
*/
getContext2D: function (level, x, y) {
var context = null;
if (level >= this.minLevel && level <= this.maxLevel) {
context = this.levels[level].context2D;
}
return context;
},
/**
* @private Build the differents levels of the pyramid if possible
* (canvas API enabled and no canvas tainting issue)
@ -239,33 +253,28 @@
return levels;
}
levels.splice(0, 0, {
url: bigCanvas.toDataURL(),
context2D: bigContext,
width: currentWidth,
height: currentHeight
});
var smallCanvas = document.createElement("canvas");
var smallContext = smallCanvas.getContext("2d");
while (currentWidth >= minWidth * 2 && currentHeight >= minHeight * 2) {
currentWidth = Math.floor(currentWidth / 2);
currentHeight = Math.floor(currentHeight / 2);
var smallCanvas = document.createElement("canvas");
var smallContext = smallCanvas.getContext("2d");
smallCanvas.width = currentWidth;
smallCanvas.height = currentHeight;
smallContext.drawImage(bigCanvas, 0, 0, currentWidth, currentHeight);
levels.splice(0, 0, {
url: smallCanvas.toDataURL(),
context2D: smallContext,
width: currentWidth,
height: currentHeight
});
var tempCanvas = bigCanvas;
bigCanvas = smallCanvas;
smallCanvas = tempCanvas;
var tempContext = bigContext;
bigContext = smallContext;
smallContext = tempContext;
}
return levels;
}

View File

@ -45,8 +45,10 @@
* @param {Boolean} exists Is this tile a part of a sparse image? ( Also has
* this tile failed to load? )
* @param {String} url The URL of this tile's image.
* @param {CanvasRenderingContext2D} context2D The context2D of this tile if it
* is provided directly by the tile source.
*/
$.Tile = function(level, x, y, bounds, exists, url) {
$.Tile = function(level, x, y, bounds, exists, url, context2D) {
/**
* The zoom level this tile belongs to.
* @member {Number} level
@ -83,6 +85,12 @@ $.Tile = function(level, x, y, bounds, exists, url) {
* @memberof OpenSeadragon.Tile#
*/
this.url = url;
/**
* The context2D of this tile if it is provided directly by the tile source.
* @member {CanvasRenderingContext2D} context2D
* @memberOf OpenSeadragon.Tile#
*/
this.context2D = context2D;
/**
* Is this tile loaded?
* @member {Boolean} loaded
@ -247,14 +255,14 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{
size = this.size,
rendered;
if (!this.cacheImageRecord) {
if (!this.context2D && !this.cacheImageRecord) {
$.console.warn(
'[Tile.drawCanvas] attempting to draw tile %s when it\'s not cached',
this.toString());
return;
}
rendered = this.cacheImageRecord.getRenderedContext();
rendered = this.context2D || this.cacheImageRecord.getRenderedContext();
if ( !this.loaded || !rendered ){
$.console.warn(
@ -273,7 +281,8 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{
//ie its done fading or fading is turned off, and if we are drawing
//an image with an alpha channel, then the only way
//to avoid seeing the tile underneath is to clear the rectangle
if( context.globalAlpha == 1 && this.url.match('.png') ){
if (context.globalAlpha === 1 &&
(this.context2D || this.url.match('.png'))) {
//clearing only the inside of the rectangle occupied
//by the png prevents edge flikering
context.clearRect(

View File

@ -791,7 +791,7 @@ function updateViewport( tiledImage ) {
drawTiles( tiledImage, tiledImage.lastDrawn );
// Load the new 'best' tile
if ( best ) {
if (best && !best.context2D) {
loadTile( tiledImage, best, currentTime );
}
@ -936,10 +936,14 @@ function updateTile( tiledImage, drawLevel, haveDrawn, x, y, level, levelOpacity
);
if (!tile.loaded) {
var imageRecord = tiledImage._tileCache.getImageRecord(tile.url);
if (imageRecord) {
var image = imageRecord.getImage();
setTileLoaded(tiledImage, tile, image);
if (tile.context2D) {
setTileLoaded(tiledImage, tile);
} else {
var imageRecord = tiledImage._tileCache.getImageRecord(tile.url);
if (imageRecord) {
var image = imageRecord.getImage();
setTileLoaded(tiledImage, tile, image);
}
}
}
@ -972,6 +976,7 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, worldWid
bounds,
exists,
url,
context2D,
tile;
if ( !tilesMatrix[ level ] ) {
@ -987,6 +992,8 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, worldWid
bounds = tileSource.getTileBounds( level, xMod, yMod );
exists = tileSource.tileExists( level, xMod, yMod );
url = tileSource.getTileUrl( level, xMod, yMod );
context2D = tileSource.getContext2D ?
tileSource.getContext2D(level, xMod, yMod) : undefined;
bounds.x += ( x - xMod ) / numTiles.x;
bounds.y += (worldHeight / worldWidth) * (( y - yMod ) / numTiles.y);
@ -997,7 +1004,8 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, worldWid
y,
bounds,
exists,
url
url,
context2D
);
}
@ -1076,12 +1084,14 @@ function setTileLoaded(tiledImage, tile, image, cutoff) {
if (increment === 0) {
tile.loading = false;
tile.loaded = true;
tiledImage._tileCache.cacheTile({
image: image,
tile: tile,
cutoff: cutoff,
tiledImage: tiledImage
});
if (!tile.context2D) {
tiledImage._tileCache.cacheTile({
image: image,
tile: tile,
cutoff: cutoff,
tiledImage: tiledImage
});
}
tiledImage._needsDraw = true;
}
}