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; 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 * @private Build the differents levels of the pyramid if possible
* (canvas API enabled and no canvas tainting issue) * (canvas API enabled and no canvas tainting issue)
@ -239,33 +253,28 @@
return levels; return levels;
} }
levels.splice(0, 0, { levels.splice(0, 0, {
url: bigCanvas.toDataURL(), context2D: bigContext,
width: currentWidth, width: currentWidth,
height: currentHeight height: currentHeight
}); });
var smallCanvas = document.createElement("canvas");
var smallContext = smallCanvas.getContext("2d");
while (currentWidth >= minWidth * 2 && currentHeight >= minHeight * 2) { while (currentWidth >= minWidth * 2 && currentHeight >= minHeight * 2) {
currentWidth = Math.floor(currentWidth / 2); currentWidth = Math.floor(currentWidth / 2);
currentHeight = Math.floor(currentHeight / 2); currentHeight = Math.floor(currentHeight / 2);
var smallCanvas = document.createElement("canvas");
var smallContext = smallCanvas.getContext("2d");
smallCanvas.width = currentWidth; smallCanvas.width = currentWidth;
smallCanvas.height = currentHeight; smallCanvas.height = currentHeight;
smallContext.drawImage(bigCanvas, 0, 0, currentWidth, currentHeight); smallContext.drawImage(bigCanvas, 0, 0, currentWidth, currentHeight);
levels.splice(0, 0, { levels.splice(0, 0, {
url: smallCanvas.toDataURL(), context2D: smallContext,
width: currentWidth, width: currentWidth,
height: currentHeight height: currentHeight
}); });
var tempCanvas = bigCanvas;
bigCanvas = smallCanvas; bigCanvas = smallCanvas;
smallCanvas = tempCanvas;
var tempContext = bigContext;
bigContext = smallContext; bigContext = smallContext;
smallContext = tempContext;
} }
return levels; return levels;
} }

View File

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

View File

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