From 6ceabfe345de9f5ffaa1dce551c503e3ced07fab Mon Sep 17 00:00:00 2001 From: Mike Byrne Date: Wed, 4 Dec 2024 22:09:11 +0000 Subject: [PATCH 1/3] halt fine-uploader upload until after image loaded The issue: some jpegs are taken in one orientation and then rotated on a device and exported such that the display of the image doesn't seem to match the dimensions. The result is you upload what you think is a portrait image but is actually a landscape image, which EXIF data set to rotate the image. This then gives un-expected results in the image cropping tool and on the front end. The fix: halt the fine-uploader by using a promise on the submit callback of fine-uploader, until after the image has loaded and JavaScript has had a change to grab the image dimensions. (previously the upload was completing before the image had been loaded and so image dimensions were not being sent) --- .../js/components/media-library/Uploader.vue | 75 ++++++++++--------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/frontend/js/components/media-library/Uploader.vue b/frontend/js/components/media-library/Uploader.vue index 28fbfbcca..3a7ae6b4e 100644 --- a/frontend/js/components/media-library/Uploader.vue +++ b/frontend/js/components/media-library/Uploader.vue @@ -197,46 +197,53 @@ this.uploadProgress(0) }, _onSubmitCallback (id, name) { - this.$emit('clear') - // each upload session will add upload files with original filenames in a folder named using a uuid - this.unique_folder_name = this.unique_folder_name || (this.uploaderConfig.endpointRoot + qq.getUniqueId()) - this._uploader.methods.setParams({ - unique_folder_name: this.unique_folder_name, - media_to_replace_id: this.media_to_replace_id - }, id) + return new Promise((resolve, reject) => { + // halt fine uploader upload until image is loaded + // so we can send image dimensions with the upload + const img = new Image() + img.onload = () => { + this.$emit('clear') + // each upload session will add upload files with original filenames in a folder named using a uuid + this.unique_folder_name = this.unique_folder_name || (this.uploaderConfig.endpointRoot + qq.getUniqueId()) - // determine the image dimensions and add it to params sent on upload success - const imageUrl = URL.createObjectURL(this._uploader.methods.getFile(id)) - const img = new Image() + // determine the image dimensions and add it to params sent on upload success + this._uploader.methods.setParams({ + width: img.width, + height: img.height, + unique_folder_name: this.unique_folder_name, + media_to_replace_id: this.media_to_replace_id + }, id) - img.onload = () => { - this._uploader.methods.setParams({ - width: img.width, - height: img.height, - unique_folder_name: this.unique_folder_name, - media_to_replace_id: this.media_to_replace_id - }, id) - this.media_to_replace_id = null - } + this.media_to_replace_id = null - img.src = imageUrl + const media = { + id: this._uploader.methods.getUuid(id), + name: sanitizeFilename(name), + progress: 0, + error: false, + errorMessage: null, + isReplacement: !!this.media_to_replace_id, + replacementId: this.media_to_replace_id + } - const media = { - id: this._uploader.methods.getUuid(id), - name: sanitizeFilename(name), - progress: 0, - error: false, - errorMessage: null, - isReplacement: !!this.media_to_replace_id, - replacementId: this.media_to_replace_id - } + if (this.type.value === 'file') { + this.media_to_replace_id = null + } - if (this.type.value === 'file') { - this.media_to_replace_id = null - } + this.loadingMedias.push(media) + this.loadingProgress(media) + + // resolve the promise, allow the upload to continue + resolve(img) + } + + img.onerror = (err) => { + console.error(err) // eslint-disable-line + reject(err); + } - this.loadingMedias.push(media) - this.loadingProgress(media) + img.src = URL.createObjectURL(this._uploader.methods.getFile(id)) + }); }, _onProgressCallback (id, name, uploadedBytes, totalBytes) { const index = this.loadingMedias.findIndex((m) => m.id === this._uploader.methods.getUuid(id)) From a08abad40084e709b9c97deca07924bd096bf2c7 Mon Sep 17 00:00:00 2001 From: Mike Byrne Date: Thu, 5 Dec 2024 12:26:15 +0000 Subject: [PATCH 2/3] use dimensions sent from frontend when storing image --- src/Http/Controllers/Admin/MediaLibraryController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Http/Controllers/Admin/MediaLibraryController.php b/src/Http/Controllers/Admin/MediaLibraryController.php index 6b11e2b75..fee292e37 100644 --- a/src/Http/Controllers/Admin/MediaLibraryController.php +++ b/src/Http/Controllers/Admin/MediaLibraryController.php @@ -187,6 +187,11 @@ public function storeFile($request) [$w, $h] = getimagesize($uploadedFile->path()); + if ($request->input('width') && $request->input('height')) { + $w = $request->input('width'); + $h = $request->input('height'); + } + $uploadedFile->storeAs($fileDirectory, $filename, $disk); $fields = [ From 67411a919d580e7da0b8b64dc55fd06ba311cbc6 Mon Sep 17 00:00:00 2001 From: Mike Byrne Date: Thu, 5 Dec 2024 14:14:09 +0000 Subject: [PATCH 3/3] skip getting image size if supplied by front end --- src/Http/Controllers/Admin/MediaLibraryController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Http/Controllers/Admin/MediaLibraryController.php b/src/Http/Controllers/Admin/MediaLibraryController.php index fee292e37..bbe69e0e2 100644 --- a/src/Http/Controllers/Admin/MediaLibraryController.php +++ b/src/Http/Controllers/Admin/MediaLibraryController.php @@ -185,11 +185,11 @@ public function storeFile($request) $uploadedFile = $request->file('qqfile'); - [$w, $h] = getimagesize($uploadedFile->path()); - if ($request->input('width') && $request->input('height')) { $w = $request->input('width'); $h = $request->input('height'); + } else { + [$w, $h] = getimagesize($uploadedFile->path()); } $uploadedFile->storeAs($fileDirectory, $filename, $disk);