From 515f0c48ebb24c856c69612def0060cd81e445c9 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Wed, 9 Nov 2022 22:43:58 -0800 Subject: [PATCH] editor: heic --- CHANGELOG.md | 1 + appinfo/routes.php | 1 + lib/Controller/ApiBase.php | 6 +++--- lib/Controller/ImageController.php | 25 ++++++++++++++++++------- src/components/ImageEditor.vue | 11 ++++++++++- src/components/Viewer.vue | 2 +- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b91bf93..70dc2fc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ This file is manually updated. Please file an issue if something is missing. - Fix stretched images in viewer ([#176](https://github.com/pulsejet/memories/issues/176)) - Editor: Restore metadata after image edit ([#174](https://github.com/pulsejet/memories/issues/174)) - Editor: Fix loss of resolution after edit +- Editor: Allow editing all image formats (HEIC etc.) ## v4.6.1, v3.6.1 (2022-11-07) diff --git a/appinfo/routes.php b/appinfo/routes.php index 32b99163..6915ed88 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -54,6 +54,7 @@ return [ ['name' => 'Image#info', 'url' => '/api/image/info/{id}', 'verb' => 'GET'], ['name' => 'Image#setExif', 'url' => '/api/image/set-exif/{id}', 'verb' => 'PATCH'], + ['name' => 'Image#jpeg', 'url' => '/api/image/jpeg/{id}', 'verb' => 'GET'], ['name' => 'Archive#archive', 'url' => '/api/archive/{id}', 'verb' => 'PATCH'], diff --git a/lib/Controller/ApiBase.php b/lib/Controller/ApiBase.php index 072ab26d..3d3ef667 100644 --- a/lib/Controller/ApiBase.php +++ b/lib/Controller/ApiBase.php @@ -135,11 +135,11 @@ class ApiBase extends Controller } /** - * Get a file with ID from user's folder + * Get a file with ID from user's folder. * * @param int $fileId * - * @return File|null + * @return null|File */ protected function getUserFile(int $id) { @@ -156,7 +156,7 @@ class ApiBase extends Controller } // Check if node is a file - if (!($file[0] instanceof File)) { + if (!$file[0] instanceof File) { return null; } diff --git a/lib/Controller/ImageController.php b/lib/Controller/ImageController.php index 3c182e76..43531472 100644 --- a/lib/Controller/ImageController.php +++ b/lib/Controller/ImageController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\AppInfo\Application; use OCA\Memories\Exif; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -96,25 +97,35 @@ class ImageController extends ApiBase } /** - * Get a full resolution PNG for editing from a file. + * @NoAdminRequired + * + * @NoCSRFRequired + * + * Get a full resolution JPEG for editing from a file. */ - public function getPNG(string $id) + public function jpeg(string $id) { $file = $this->getUserFile((int) $id); if (!$file) { return new JSONResponse([], Http::STATUS_NOT_FOUND); } - // Get the image info - $info = $this->timelineQuery->getInfoById($file->getId(), true); + // check if valid image + $mimetype = $file->getMimeType(); + if (!\in_array($mimetype, Application::IMAGE_MIMES, true)) { + return new JSONResponse([], Http::STATUS_FORBIDDEN); + } // Get the image $path = $file->getStorage()->getLocalFile($file->getInternalPath()); - $image = Exif::getPNG($path, $info['exif']); + $image = new \Imagick($path); + $image->setImageFormat('jpeg'); + $image->setImageCompressionQuality(95); + $blob = $image->getImageBlob(); // Return the image - $response = new Http\DataDisplayResponse($image, Http::STATUS_OK, ['Content-Type' => 'image/png']); - $response->cacheFor(0); + $response = new Http\DataDisplayResponse($blob, Http::STATUS_OK, ['Content-Type' => $image->getImageMimeType()]); + $response->cacheFor(3600 * 24, false, false); return $response; } diff --git a/src/components/ImageEditor.vue b/src/components/ImageEditor.vue index 1b76e9b8..be4c2422 100644 --- a/src/components/ImageEditor.vue +++ b/src/components/ImageEditor.vue @@ -32,8 +32,17 @@ export default class ImageEditor extends Mixins(GlobalMixin) { private imageEditor: FilerobotImageEditor = null; get config(): FilerobotImageEditorConfig & { theme: any } { + let src: string; + if (["image/png", "image/jpeg", "image/webp"].includes(this.mime)) { + src = this.src; + } else { + src = generateUrl("/apps/memories/api/image/jpeg/{fileid}", { + fileid: this.fileid, + }); + } + return { - source: this.src, + source: src, defaultSavedImageName: this.defaultSavedImageName, defaultSavedImageType: this.defaultSavedImageType, diff --git a/src/components/Viewer.vue b/src/components/Viewer.vue index d0bc8859..001e2d26 100644 --- a/src/components/Viewer.vue +++ b/src/components/Viewer.vue @@ -586,7 +586,7 @@ export default class Viewer extends Mixins(GlobalMixin) { } get canEdit() { - return ["image/jpeg", "image/png"].includes(this.currentPhoto?.mimetype); + return this.currentPhoto?.mimetype?.startsWith("image/"); } private openEditor() {