From 86c9deb7b8a26df96094e21499809765cea2d882 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Tue, 14 May 2024 14:13:41 +0530 Subject: [PATCH] Last util --- web/apps/photos/src/constants/mlConfig.ts | 0 .../services/machineLearning/faceService.ts | 7 +- .../services/machineLearning/peopleService.ts | 2 +- .../services/machineLearning/readerService.ts | 109 +++++++++++++++++- .../photos/src/types/machineLearning/ui.ts | 0 .../photos/src/utils/machineLearning/index.ts | 103 ----------------- 6 files changed, 108 insertions(+), 113 deletions(-) delete mode 100644 web/apps/photos/src/constants/mlConfig.ts delete mode 100644 web/apps/photos/src/types/machineLearning/ui.ts delete mode 100644 web/apps/photos/src/utils/machineLearning/index.ts diff --git a/web/apps/photos/src/constants/mlConfig.ts b/web/apps/photos/src/constants/mlConfig.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/web/apps/photos/src/services/machineLearning/faceService.ts b/web/apps/photos/src/services/machineLearning/faceService.ts index cf5e6a573..c447fe396 100644 --- a/web/apps/photos/src/services/machineLearning/faceService.ts +++ b/web/apps/photos/src/services/machineLearning/faceService.ts @@ -9,13 +9,12 @@ import { type Versioned, } from "services/ml/types"; import { imageBitmapToBlob, warpAffineFloat32List } from "utils/image"; -import { +import mlIDbStorage from "utils/storage/mlIDbStorage"; +import ReaderService, { getFaceId, getLocalFile, getOriginalImageBitmap, -} from "utils/machineLearning"; -import mlIDbStorage from "utils/storage/mlIDbStorage"; -import ReaderService from "./readerService"; +} from "./readerService"; class FaceService { async syncFileFaceDetections( diff --git a/web/apps/photos/src/services/machineLearning/peopleService.ts b/web/apps/photos/src/services/machineLearning/peopleService.ts index aa9c22e2f..5c515afe3 100644 --- a/web/apps/photos/src/services/machineLearning/peopleService.ts +++ b/web/apps/photos/src/services/machineLearning/peopleService.ts @@ -1,8 +1,8 @@ import log from "@/next/log"; import { Face, MLSyncContext, Person } from "services/ml/types"; -import { getLocalFile, getOriginalImageBitmap } from "utils/machineLearning"; import mlIDbStorage from "utils/storage/mlIDbStorage"; import FaceService, { isDifferentOrOld } from "./faceService"; +import { getLocalFile, getOriginalImageBitmap } from "./readerService"; class PeopleService { async syncPeopleIndex(syncContext: MLSyncContext) { diff --git a/web/apps/photos/src/services/machineLearning/readerService.ts b/web/apps/photos/src/services/machineLearning/readerService.ts index 44d0738f5..6ad4c80e8 100644 --- a/web/apps/photos/src/services/machineLearning/readerService.ts +++ b/web/apps/photos/src/services/machineLearning/readerService.ts @@ -1,11 +1,18 @@ import { FILE_TYPE } from "@/media/file-type"; +import { decodeLivePhoto } from "@/media/live-photo"; import log from "@/next/log"; -import { MLSyncContext, MLSyncFileContext } from "services/ml/types"; +import PQueue from "p-queue"; +import DownloadManager from "services/download"; +import { getLocalFiles } from "services/fileService"; +import { Dimensions } from "services/ml/geom"; import { - getLocalFileImageBitmap, - getOriginalImageBitmap, - getThumbnailImageBitmap, -} from "utils/machineLearning"; + DetectedFace, + MLSyncContext, + MLSyncFileContext, +} from "services/ml/types"; +import { EnteFile } from "types/file"; +import { getRenderableImage } from "utils/file"; +import { clamp } from "utils/image"; class ReaderService { async getImageBitmap( @@ -55,3 +62,95 @@ class ReaderService { } } export default new ReaderService(); + +export async function getLocalFile(fileId: number) { + const localFiles = await getLocalFiles(); + return localFiles.find((f) => f.id === fileId); +} + +export function getFaceId(detectedFace: DetectedFace, imageDims: Dimensions) { + const xMin = clamp( + detectedFace.detection.box.x / imageDims.width, + 0.0, + 0.999999, + ) + .toFixed(5) + .substring(2); + const yMin = clamp( + detectedFace.detection.box.y / imageDims.height, + 0.0, + 0.999999, + ) + .toFixed(5) + .substring(2); + const xMax = clamp( + (detectedFace.detection.box.x + detectedFace.detection.box.width) / + imageDims.width, + 0.0, + 0.999999, + ) + .toFixed(5) + .substring(2); + const yMax = clamp( + (detectedFace.detection.box.y + detectedFace.detection.box.height) / + imageDims.height, + 0.0, + 0.999999, + ) + .toFixed(5) + .substring(2); + + const rawFaceID = `${xMin}_${yMin}_${xMax}_${yMax}`; + const faceID = `${detectedFace.fileId}_${rawFaceID}`; + + return faceID; +} + +async function getImageBlobBitmap(blob: Blob): Promise { + return await createImageBitmap(blob); +} + +async function getOriginalFile(file: EnteFile, queue?: PQueue) { + let fileStream; + if (queue) { + fileStream = await queue.add(() => DownloadManager.getFile(file)); + } else { + fileStream = await DownloadManager.getFile(file); + } + return new Response(fileStream).blob(); +} + +async function getOriginalConvertedFile(file: EnteFile, queue?: PQueue) { + const fileBlob = await getOriginalFile(file, queue); + if (file.metadata.fileType === FILE_TYPE.IMAGE) { + return await getRenderableImage(file.metadata.title, fileBlob); + } else { + const { imageFileName, imageData } = await decodeLivePhoto( + file.metadata.title, + fileBlob, + ); + return await getRenderableImage(imageFileName, new Blob([imageData])); + } +} + +export async function getOriginalImageBitmap(file: EnteFile, queue?: PQueue) { + const fileBlob = await getOriginalConvertedFile(file, queue); + log.info("[MLService] Got file: ", file.id.toString()); + return getImageBlobBitmap(fileBlob); +} + +export async function getThumbnailImageBitmap(file: EnteFile) { + const thumb = await DownloadManager.getThumbnail(file); + log.info("[MLService] Got thumbnail: ", file.id.toString()); + + return getImageBlobBitmap(new Blob([thumb])); +} + +export async function getLocalFileImageBitmap( + enteFile: EnteFile, + localFile: globalThis.File, +) { + let fileBlob = localFile as Blob; + fileBlob = await getRenderableImage(enteFile.metadata.title, fileBlob); + return getImageBlobBitmap(fileBlob); +} diff --git a/web/apps/photos/src/types/machineLearning/ui.ts b/web/apps/photos/src/types/machineLearning/ui.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/web/apps/photos/src/utils/machineLearning/index.ts b/web/apps/photos/src/utils/machineLearning/index.ts deleted file mode 100644 index 737de4d1f..000000000 --- a/web/apps/photos/src/utils/machineLearning/index.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { FILE_TYPE } from "@/media/file-type"; -import { decodeLivePhoto } from "@/media/live-photo"; -import log from "@/next/log"; -import PQueue from "p-queue"; -import DownloadManager from "services/download"; -import { getLocalFiles } from "services/fileService"; -import { Dimensions } from "services/ml/geom"; -import { DetectedFace } from "services/ml/types"; -import { EnteFile } from "types/file"; -import { getRenderableImage } from "utils/file"; -import { clamp } from "utils/image"; - -export async function getLocalFile(fileId: number) { - const localFiles = await getLocalFiles(); - return localFiles.find((f) => f.id === fileId); -} - -export function getFaceId(detectedFace: DetectedFace, imageDims: Dimensions) { - const xMin = clamp( - detectedFace.detection.box.x / imageDims.width, - 0.0, - 0.999999, - ) - .toFixed(5) - .substring(2); - const yMin = clamp( - detectedFace.detection.box.y / imageDims.height, - 0.0, - 0.999999, - ) - .toFixed(5) - .substring(2); - const xMax = clamp( - (detectedFace.detection.box.x + detectedFace.detection.box.width) / - imageDims.width, - 0.0, - 0.999999, - ) - .toFixed(5) - .substring(2); - const yMax = clamp( - (detectedFace.detection.box.y + detectedFace.detection.box.height) / - imageDims.height, - 0.0, - 0.999999, - ) - .toFixed(5) - .substring(2); - - const rawFaceID = `${xMin}_${yMin}_${xMax}_${yMax}`; - const faceID = `${detectedFace.fileId}_${rawFaceID}`; - - return faceID; -} - -async function getImageBlobBitmap(blob: Blob): Promise { - return await createImageBitmap(blob); -} - -async function getOriginalFile(file: EnteFile, queue?: PQueue) { - let fileStream; - if (queue) { - fileStream = await queue.add(() => DownloadManager.getFile(file)); - } else { - fileStream = await DownloadManager.getFile(file); - } - return new Response(fileStream).blob(); -} - -async function getOriginalConvertedFile(file: EnteFile, queue?: PQueue) { - const fileBlob = await getOriginalFile(file, queue); - if (file.metadata.fileType === FILE_TYPE.IMAGE) { - return await getRenderableImage(file.metadata.title, fileBlob); - } else { - const { imageFileName, imageData } = await decodeLivePhoto( - file.metadata.title, - fileBlob, - ); - return await getRenderableImage(imageFileName, new Blob([imageData])); - } -} - -export async function getOriginalImageBitmap(file: EnteFile, queue?: PQueue) { - const fileBlob = await getOriginalConvertedFile(file, queue); - log.info("[MLService] Got file: ", file.id.toString()); - return getImageBlobBitmap(fileBlob); -} - -export async function getThumbnailImageBitmap(file: EnteFile) { - const thumb = await DownloadManager.getThumbnail(file); - log.info("[MLService] Got thumbnail: ", file.id.toString()); - - return getImageBlobBitmap(new Blob([thumb])); -} - -export async function getLocalFileImageBitmap( - enteFile: EnteFile, - localFile: globalThis.File, -) { - let fileBlob = localFile as Blob; - fileBlob = await getRenderableImage(enteFile.metadata.title, fileBlob); - return getImageBlobBitmap(fileBlob); -}