浏览代码

Reduce concepts

Manav Rathi 1 年之前
父节点
当前提交
c8f04f35ba
共有 1 个文件被更改,包括 45 次插入60 次删除
  1. 45 60
      web/apps/photos/src/services/upload/thumbnailService.ts

+ 45 - 60
web/apps/photos/src/services/upload/thumbnailService.ts

@@ -11,19 +11,16 @@ import { ElectronFile, FileTypeInfo } from "types/upload";
 import { isFileHEIC } from "utils/file";
 import { getUint8ArrayView } from "../readerService";
 
-const MAX_THUMBNAIL_DIMENSION = 720;
+/** Maximum width or height of the generated thumbnail */
+const maxThumbnailDimension = 720;
+/** Maximum size (in bytes) of the generated thumbnail */
+const maxThumbnailSize = 100 * 1024; // 100 KB
 const MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF = 10;
-const MAX_THUMBNAIL_SIZE = 100 * 1024;
 const MIN_QUALITY = 0.5;
 const MAX_QUALITY = 0.7;
 
 const WAIT_TIME_THUMBNAIL_GENERATION = 30 * 1000;
 
-interface Dimension {
-    width: number;
-    height: number;
-}
-
 export async function generateThumbnail(
     file: File | ElectronFile,
     fileTypeInfo: FileTypeInfo,
@@ -38,7 +35,7 @@ export async function generateThumbnail(
             } else {
                 thumbnail = await generateVideoThumbnail(file, fileTypeInfo);
             }
-            if (thumbnail.length > 1.5 * MAX_THUMBNAIL_SIZE) {
+            if (thumbnail.length > 1.5 * maxThumbnailSize) {
                 log.error(
                     `thumbnail greater than max limit - ${JSON.stringify({
                         thumbnailSize: convertBytesToHumanReadable(
@@ -80,8 +77,8 @@ async function generateImageThumbnail(
         try {
             return await generateImageThumbnailInElectron(
                 file,
-                MAX_THUMBNAIL_DIMENSION,
-                MAX_THUMBNAIL_SIZE,
+                maxThumbnailDimension,
+                maxThumbnailSize,
             );
         } catch (e) {
             return await generateImageThumbnailUsingCanvas(file, fileTypeInfo);
@@ -149,23 +146,14 @@ async function generateImageThumbnailUsingCanvas(
         image.onload = () => {
             try {
                 URL.revokeObjectURL(imageURL);
-                const imageDimension = {
-                    width: image.width,
-                    height: image.height,
-                };
-                const thumbnailDimension = calculateThumbnailDimension(
-                    imageDimension,
-                    MAX_THUMBNAIL_DIMENSION,
-                );
-                canvas.width = thumbnailDimension.width;
-                canvas.height = thumbnailDimension.height;
-                canvasCTX.drawImage(
-                    image,
-                    0,
-                    0,
-                    thumbnailDimension.width,
-                    thumbnailDimension.height,
+                const { width, height } = scaledThumbnailDimensions(
+                    image.width,
+                    image.height,
+                    maxThumbnailDimension,
                 );
+                canvas.width = width;
+                canvas.height = height;
+                canvasCTX.drawImage(image, 0, 0, width, height);
                 image = null;
                 clearTimeout(timeout);
                 resolve(null);
@@ -233,23 +221,14 @@ async function generateVideoThumbnailUsingCanvas(file: File | ElectronFile) {
                 if (!video) {
                     throw Error("video load failed");
                 }
-                const videoDimension = {
-                    width: video.videoWidth,
-                    height: video.videoHeight,
-                };
-                const thumbnailDimension = calculateThumbnailDimension(
-                    videoDimension,
-                    MAX_THUMBNAIL_DIMENSION,
-                );
-                canvas.width = thumbnailDimension.width;
-                canvas.height = thumbnailDimension.height;
-                canvasCTX.drawImage(
-                    video,
-                    0,
-                    0,
-                    thumbnailDimension.width,
-                    thumbnailDimension.height,
+                const { width, height } = scaledThumbnailDimensions(
+                    video.videoWidth,
+                    video.videoHeight,
+                    maxThumbnailDimension,
                 );
+                canvas.width = width;
+                canvas.height = height;
+                canvasCTX.drawImage(video, 0, 0, width, height);
                 video = null;
                 clearTimeout(timeout);
                 resolve(null);
@@ -292,7 +271,7 @@ async function getCompressedThumbnailBlobFromCanvas(canvas: HTMLCanvasElement) {
         quality -= 0.1;
     } while (
         quality >= MIN_QUALITY &&
-        thumbnailBlob.size > MAX_THUMBNAIL_SIZE &&
+        thumbnailBlob.size > maxThumbnailSize &&
         percentageSizeDiff(thumbnailBlob.size, prevSize) >=
             MIN_COMPRESSION_PERCENTAGE_SIZE_DIFF
     );
@@ -307,24 +286,30 @@ function percentageSizeDiff(
     return ((oldThumbnailSize - newThumbnailSize) * 100) / oldThumbnailSize;
 }
 
-// method to calculate new size of image for limiting it to maximum width and height, maintaining aspect ratio
-// returns {0,0} for invalid inputs
-function calculateThumbnailDimension(
-    originalDimension: Dimension,
+/**
+ * Compute the size of the thumbnail to create for an image with the given
+ * {@link width} and {@link height}.
+ *
+ * This function calculates a new size of an image for limiting it to maximum
+ * width and height (both specified by {@link maxDimension}), while maintaining
+ * aspect ratio.
+ *
+ * It returns `{0, 0}` for invalid inputs.
+ */
+const scaledThumbnailDimensions = (
+    width: number,
+    height: number,
     maxDimension: number,
-): Dimension {
-    if (originalDimension.height === 0 || originalDimension.width === 0) {
-        return { width: 0, height: 0 };
-    }
-    const widthScaleFactor = maxDimension / originalDimension.width;
-    const heightScaleFactor = maxDimension / originalDimension.height;
+): { width: number; height: number } => {
+    if (width === 0 || height === 0) return { width: 0, height: 0 };
+    const widthScaleFactor = maxDimension / width;
+    const heightScaleFactor = maxDimension / height;
     const scaleFactor = Math.min(widthScaleFactor, heightScaleFactor);
-    const thumbnailDimension = {
-        width: Math.round(originalDimension.width * scaleFactor),
-        height: Math.round(originalDimension.height * scaleFactor),
+    const thumbnailDimensions = {
+        width: Math.round(width * scaleFactor),
+        height: Math.round(height * scaleFactor),
     };
-    if (thumbnailDimension.width === 0 || thumbnailDimension.height === 0) {
+    if (thumbnailDimensions.width === 0 || thumbnailDimensions.height === 0)
         return { width: 0, height: 0 };
-    }
-    return thumbnailDimension;
-}
+    return thumbnailDimensions;
+};