From: Tim Düsterhus Date: Fri, 29 Mar 2019 14:52:37 +0000 (+0100) Subject: Split image scaling into load + resize + save instead of loadAndResize + save X-Git-Tag: 5.2.0_Alpha_1~124^2~4 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=32232ff2f27b9288690236ecc18b475316615495;p=GitHub%2FWoltLab%2FWCF.git Split image scaling into load + resize + save instead of loadAndResize + save --- diff --git a/wcfsetup/install/files/js/WCF.Attachment.js b/wcfsetup/install/files/js/WCF.Attachment.js index eb95572282..bb7c33130a 100644 --- a/wcfsetup/install/files/js/WCF.Attachment.js +++ b/wcfsetup/install/files/js/WCF.Attachment.js @@ -336,24 +336,37 @@ if (COMPILER_TARGET_DEFAULT) { }, 10000); }); - var promise = resizer.resize(file, maxWidth, maxHeight, quality, file.size > maxSize, timeout) + var promise = resizer.loadFile(file) .then((function (result) { - var fileType = this._options.autoScale.fileType; + var exif = result.exif; - if (this._options.autoScale.fileType === 'keep') { - fileType = file.type; - } - - return resizer.getFile(result, file.name, fileType, quality); + return resizer.resize(result.image, maxWidth, maxHeight, quality, file.size > maxSize, timeout) + .then((function (resizedImage) { + // Check whether the image actually was resized + if (resizedImage === undefined) { + return file; + } + + var fileType = this._options.autoScale.fileType; + + if (this._options.autoScale.fileType === 'keep') { + fileType = file.type; + } + + return resizer.saveFile({ + exif: exif, + image: resizedImage + }, file.name, fileType, quality); + }).bind(this)) + .then(function (resizedFile) { + if (resizedFile.size > file.size) { + console.debug('[WCF.Attachment] File size of "' + file.name + '" increased, uploading untouched image.'); + return file; + } + + return resizedFile; + }); }).bind(this)) - .then(function (resizedFile) { - if (resizedFile.size > file.size) { - console.debug('[WCF.Attachment] File size of "' + file.name + '" increased, uploading untouched image.'); - return file; - } - - return resizedFile; - }) .catch(function (error) { console.debug('[WCF.Attachment] Failed to resize image "' + file.name + '":', error); return file; diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/ImageResizer.js b/wcfsetup/install/files/js/WoltLabSuite/Core/ImageResizer.js index d572ea29ed..3765407e3f 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/ImageResizer.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/ImageResizer.js @@ -78,24 +78,24 @@ define([ }, /** - * Converts the result of ImageResizer.resize() into a File + * Converts the given object of exif data and image data into a File. * - * @param {Object{exif: Uint8Array|undefined, image: Canvas|File} result the result of ImageResizer.resize() + * @param {Object{exif: Uint8Array|undefined, image: Canvas} data object containing exif data and image data * @param {String} fileName the name of the returned file * @param {String} [fileType] the type of the returned image * @param {Number} [quality] quality setting, currently only effective for "image/jpeg" * @returns {Promise} the File object */ - getFile: function (result, fileName, fileType, quality) { + saveFile: function (data, fileName, fileType, quality) { fileType = fileType || this.fileType; quality = quality || this.quality; var basename = fileName.match(/(.+)(\..+?)$/); - return pica.toBlob(result.image, fileType, quality) + return pica.toBlob(data.image, fileType, quality) .then(function (blob) { - if (fileType === 'image/jpeg' && typeof result.exif !== 'undefined') { - return ExifUtil.setExifData(blob, result.exif); + if (fileType === 'image/jpeg' && typeof data.exif !== 'undefined') { + return ExifUtil.setExifData(blob, data.exif); } return blob; @@ -149,88 +149,55 @@ define([ /** * Downscales an image given as File object. * - * @param {File} file the image to resize + * @param {Image} image the image to resize * @param {Number} [maxWidth] maximum width * @param {Number} [maxHeight] maximum height * @param {Number} [quality] quality in percent * @param {boolean} [force] whether to force scaling even if unneeded (thus re-encoding with a possibly smaller file size) - * @param {Promise} cancelPromise a Promise used to cancel pica's operation - * @returns {Promise<{exif: any, image: any} | never>} a Promise resolving with the resized image as Canvas and optional EXIF data + * @param {Promise} cancelPromise a Promise used to cancel pica's operation when it resolves + * @returns {Promise} a Promise resolving with the resized image as a {Canvas} or undefined if no resizing happened */ - resize: function (file, maxWidth, maxHeight, quality, force, cancelPromise) { + resize: function (image, maxWidth, maxHeight, quality, force, cancelPromise) { maxWidth = maxWidth || this.maxWidth; maxHeight = maxHeight || this.maxHeight; quality = quality || this.quality; force = force || false; - - var exif; - if (file.type === 'image/jpeg') { - // Extract EXIF data - exif = ExifUtil.getExifBytesFromJpeg(file); + + var canvas = document.createElement('canvas'); + + // Prevent upscaling + var newWidth = Math.min(maxWidth, image.width); + var newHeight = Math.min(maxHeight, image.height); + + if (image.width <= newWidth && image.height <= newHeight && !force) { + return Promise.resolve(undefined); } - var resizer = new Promise(function (resolve, reject) { - var reader = new FileReader(); - var image = new Image(); - - reader.addEventListener('load', function () { - image.src = reader.result; - }); - - reader.addEventListener('error', function () { - reader.abort(); - reject(reader.error); - }); - - image.addEventListener('error', reject); - - image.addEventListener('load', function () { - var canvas = document.createElement('canvas'); - - // Prevent upscaling - var newWidth = Math.min(maxWidth, image.width); - var newHeight = Math.min(maxHeight, image.height); - - if (image.width <= newWidth && image.height <= newHeight && !force) { - return resolve(file); - } - - // Keep image ratio - if (newWidth >= newHeight) { - canvas.width = newWidth; - canvas.height = newWidth * (image.height / image.width); - } - else { - canvas.width = newHeight * (image.width / image.height); - canvas.height = newHeight; - } - - // Map to Pica's quality - var resizeQuality = 1; - if (quality >= 0.8) { - resizeQuality = 3; - } - else if (quality >= 0.4) { - resizeQuality = 2; - } - - var options = { - quality: resizeQuality, - cancelToken: cancelPromise - }; - - pica.resize(image, canvas, options).then(function (result) { - resolve(result); - }, reject); - }); - - reader.readAsDataURL(file); - }); + // Keep image ratio + if (newWidth >= newHeight) { + canvas.width = newWidth; + canvas.height = newWidth * (image.height / image.width); + } + else { + canvas.width = newHeight * (image.width / image.height); + canvas.height = newHeight; + } - return Promise.all([ exif, resizer ]) - .then(function (result) { - return { exif: result[0], image: result[1] }; - }); + // Map to Pica's quality + var resizeQuality = 1; + if (quality >= 0.8) { + resizeQuality = 3; + } + else if (quality >= 0.4) { + resizeQuality = 2; + } + + var options = { + quality: resizeQuality, + cancelToken: cancelPromise + }; + + return pica.resize(image, canvas, options); } };