GUACAMOLE-884: Merge Leverage createImageBitmap() for reading image data where supported

This commit is contained in:
Virtually Nick
2019-10-09 15:52:09 -04:00
committed by GitHub
3 changed files with 108 additions and 30 deletions

View File

@@ -1190,13 +1190,10 @@ Guacamole.Client = function(tunnel) {
// Create stream
var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
var reader = new Guacamole.DataURIReader(stream, mimetype);
// Draw image when stream is complete
reader.onend = function drawImageBlob() {
// Draw received contents once decoded
display.setChannelMask(layer, channelMask);
display.draw(layer, x, y, reader.getURI());
};
display.drawStream(layer, x, y, stream, mimetype);
},

View File

@@ -512,11 +512,17 @@ Guacamole.Display = function() {
* Draws the specified image at the given coordinates. The image specified
* must already be loaded.
*
* @param {Guacamole.Layer} layer The layer to draw upon.
* @param {Number} x The destination X coordinate.
* @param {Number} y The destination Y coordinate.
* @param {Image} image The image to draw. Note that this is an Image
* object - not a URL.
* @param {Guacamole.Layer} layer
* The layer to draw upon.
*
* @param {Number} x
* The destination X coordinate.
*
* @param {Number} y
* The destination Y coordinate.
*
* @param {CanvasImageSource} image
* The image to draw. Note that this not a URL.
*/
this.drawImage = function(layer, x, y, image) {
scheduleTask(function __display_drawImage() {
@@ -543,11 +549,35 @@ Guacamole.Display = function() {
*/
this.drawBlob = function(layer, x, y, blob) {
var task;
// Prefer createImageBitmap() over blob URLs if available
if (window.createImageBitmap) {
var bitmap;
// Draw image once loaded
task = scheduleTask(function drawImageBitmap() {
layer.drawImage(x, y, bitmap);
}, true);
// Load image from provided blob
window.createImageBitmap(blob).then(function bitmapLoaded(decoded) {
bitmap = decoded;
task.unblock();
});
}
// Use blob URLs and the Image object if createImageBitmap() is
// unavailable
else {
// Create URL for blob
var url = URL.createObjectURL(blob);
// Draw and free blob URL when ready
var task = scheduleTask(function __display_drawBlob() {
task = scheduleTask(function __display_drawBlob() {
// Draw the image only if it loaded without errors
if (image.width && image.height)
@@ -564,6 +594,53 @@ Guacamole.Display = function() {
image.onerror = task.unblock;
image.src = url;
}
};
/**
* Draws the image within the given stream at the given coordinates. The
* image will be loaded automatically, and this and any future operations
* will wait for the image to finish loading. This function will
* automatically choose an approriate method for reading and decoding the
* given image stream, and should be preferred for received streams except
* where manual decoding of the stream is unavoidable.
*
* @param {Guacamole.Layer} layer
* The layer to draw upon.
*
* @param {Number} x
* The destination X coordinate.
*
* @param {Number} y
* The destination Y coordinate.
*
* @param {Guacamole.InputStream} stream
* The stream along which image data will be received.
*
* @param {String} mimetype
* The mimetype of the image within the stream.
*/
this.drawStream = function drawStream(layer, x, y, stream, mimetype) {
// If createImageBitmap() is available, load the image as a blob so
// that function can be used
if (window.createImageBitmap) {
var reader = new Guacamole.BlobReader(stream, mimetype);
reader.onend = function drawImageBlob() {
guac_display.drawBlob(layer, x, y, reader.getBlob());
};
}
// Lacking createImageBitmap(), fall back to data URIs and the Image
// object
else {
var reader = new Guacamole.DataURIReader(stream, mimetype);
reader.onend = function drawImageDataURI() {
guac_display.draw(layer, x, y, reader.getURI());
};
}
};
/**

View File

@@ -319,10 +319,14 @@ Guacamole.Layer = function(width, height) {
* Draws the specified image at the given coordinates. The image specified
* must already be loaded.
*
* @param {Number} x The destination X coordinate.
* @param {Number} y The destination Y coordinate.
* @param {Image} image The image to draw. Note that this is an Image
* object - not a URL.
* @param {Number} x
* The destination X coordinate.
*
* @param {Number} y
* The destination Y coordinate.
*
* @param {CanvasImageSource} image
* The image to draw. Note that this is not a URL.
*/
this.drawImage = function(x, y, image) {
if (layer.autosize) fitRect(x, y, image.width, image.height);