Reduce concepts

This commit is contained in:
Manav Rathi 2024-04-20 17:59:07 +05:30
parent 19103f4961
commit c8f04f35ba
No known key found for this signature in database

View file

@ -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;
};