From e803c670f4fdb7fa7ffa3dca483f04ce611f5b31 Mon Sep 17 00:00:00 2001 From: Gabriel De Los Rios Date: Fri, 6 Feb 2026 21:41:20 -0300 Subject: [PATCH] feat: service to store images with OPFS --- src/app/services/image-storage.spec.ts | 75 ++++++++++++++++++++++++++ src/app/services/image-storage.ts | 61 +++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/app/services/image-storage.spec.ts create mode 100644 src/app/services/image-storage.ts diff --git a/src/app/services/image-storage.spec.ts b/src/app/services/image-storage.spec.ts new file mode 100644 index 0000000..1e1ea16 --- /dev/null +++ b/src/app/services/image-storage.spec.ts @@ -0,0 +1,75 @@ +import { TestBed } from '@angular/core/testing'; + +import { ImageStorage } from './image-storage'; +import { OPFS } from './opfs'; +import { FiletypeUtils } from './filetype-utils'; + +//data:image/png;base64, +const BASE64_IMG = + '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d4e7wsv9/f3hvvBS2S6xVbZLbImx8pIYKy+V7RJbZbvElhgrL4mx8lLZLrFVtktsibHykhgrL5XtEltlu8SWGCsvibHyUtkusVW2S2yJsfKSGCsvle0SW2W7xJYYCyzPXoMnxspLZbvEVtkusSXGyktirLxUtktsle0SmxmArUqv+iVAgAABAgQIEJhYQOoECBAgQIAAgf0EFAD3s9YTAQIECBB4X8BvBAgQIECAAAECBAgQ2EFAAXAHZF0QOCfgOQIECBAgQIAAAQIECBAgQGB8gZYZKgC21Nc3AQI3Cby+aWsbEyBAgAABAgQIENhdQIcECBBoIqAA2IRdpwQIrCHgjwSvoagNAgQIENhfQI8ECBAgQIAAgX0FFAD39dYbAQIECBB4K+C/BAgQIECAAAECBAgQ2ElAAXAnaN0QOCXgMQIECBAgQIAAAQIECBCYT8DXGc035q0zVgBsPQL6J0CAAAECBAgQIECAAIEZBORI4EsBX2f0JYUfdhJQANwJWjcECBAgQIAAAQIEDgcGBAgQIECAAIH9BRQA9zfXIwECBAjMLiB/AgQIECBAgAABAgQI7CigALgjtq4IPBbwMwECBAgQ2FTAlwttyqtxAgQIECBAgMClAhXWUwCsMApiIECAAAECBAisLeDLhdYW1R4BAgRuEbAtAQIEmgooADbl1zkBAgQIECBAgMA8AjIlQIAAAQIECLQRUABs4168V/cMFR8g4REg0LOA2AkQIECAAAECBAhsLuC6fnPizjpQAOxswPYJ1z1DWztrnwABAgQIECBAgAABAgQIbCfgun4722UtV1lbAbDKSIiDAAECBAgQIECAAAECBEYUkBMBAgSaCygANh8CAbwTMEX5nYWfCBAgQIAAgbEEZEOAAAECBAgQaCegANjOXs8fCJii/AGJBwgQGEtANgQIECBAgAABAgQIEGggoADYAF2XcwvIngABAgQIECBAgAABAgQIEBhfoFKGCoCVRkMsBAgQWEHAzfQrIGqCAAECBHYX8P61O7kO9xHQCwECBEoIKACWGAZBECBAYD0BN9OvZ6klAgQIrCOglUsEvH9domQdAgQIECBwnYAC4HVutiJAgAABAssErE2AAAECBAgQIECAAIFGAgqAjeB1O6eArAkQIECAAAECBAgQIECAAIHxBaplqABYbUTEQ4AAAQIECBAgQIDADQK+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'; + +describe('ImageStorage', () => { + let service: ImageStorage; + + let opfsService: Partial; + let filetypeUtils: Partial; + let FILENAME_MOCK: string; + + beforeEach(() => { + opfsService = { + writeTo: vi.fn().mockResolvedValue(undefined), + readFrom: vi.fn().mockResolvedValue(new ArrayBuffer()), + delete: vi.fn().mockResolvedValue(undefined), + }; + filetypeUtils = { + getImageExtensionFromMimeType: vi.fn().mockReturnValue('png'), + getImageMimeTypeFromFilename: vi.fn().mockReturnValue('image/png'), + }; + FILENAME_MOCK = 'mock.jpg'; + + TestBed.configureTestingModule({ + providers: [ + { provide: OPFS, useValue: opfsService }, + { provide: FiletypeUtils, useValue: filetypeUtils }, + ], + }); + service = TestBed.inject(ImageStorage); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should return blob after processing image', async () => { + //prepare file + const byteArray = Uint8Array.from(atob(BASE64_IMG), (c) => c.charCodeAt(0)); + const blob = new Blob([byteArray], { type: 'image/png' }); + const file = new File([blob], FILENAME_MOCK, { type: 'image/png' }); + + const fileName = await service.saveImage(file); + expect(typeof fileName).toBe('string'); + }); + + it('should call OPFS read on get image', async () => { + await service.getImage(FILENAME_MOCK); + expect(opfsService.readFrom).toHaveBeenCalledExactlyOnceWith( + FILENAME_MOCK, + ImageStorage['IMAGES_DIR'], + ); + }); + + it('should get image objectURL on getImageURL', async () => { + vi.spyOn(service, 'getImage').mockResolvedValue(new Blob([])); + const createObjectURLSpy = vi.spyOn(URL, 'createObjectURL'); + await service.getImageURL(FILENAME_MOCK); + expect(createObjectURLSpy).toHaveBeenCalledOnce(); + }); + + it('should call OPFS delete on delete image', () => { + service.deleteImage(FILENAME_MOCK); + expect(opfsService.delete).toHaveBeenCalledExactlyOnceWith( + FILENAME_MOCK, + ImageStorage['IMAGES_DIR'], + ); + }); +}); diff --git a/src/app/services/image-storage.ts b/src/app/services/image-storage.ts new file mode 100644 index 0000000..e7e3840 --- /dev/null +++ b/src/app/services/image-storage.ts @@ -0,0 +1,61 @@ +import { inject, Injectable } from '@angular/core'; +import { OPFS } from './opfs'; +import { FiletypeUtils } from './filetype-utils'; + +@Injectable({ + providedIn: 'root', +}) +export class ImageStorage { + private static readonly IMAGES_DIR = 'images'; + + private readonly filetypeUtils = inject(FiletypeUtils); + private readonly OPFS = inject(OPFS); + + async saveImage(imageFile: File) { + const processedBlob = await this.processImage(imageFile, 300, 0.7); + const filename = + String(Date.now()) + '.' + this.filetypeUtils.getImageExtensionFromMimeType(processedBlob.type); + await this.OPFS.writeTo(filename, ImageStorage.IMAGES_DIR, await processedBlob.arrayBuffer()); + return filename; + } + + private async processImage(file: File, maxWidth: number, quality = 0.8): Promise { + return new Promise((resolve) => { + const img = new Image(); + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d')!; + + img.onload = () => { + let { width, height } = img; + + if (width > maxWidth) { + height = (height * maxWidth) / width; + width = maxWidth; + } + + canvas.width = width; + canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + + canvas.toBlob((blob) => resolve(blob!), file.type, quality); + }; + + img.src = URL.createObjectURL(file); + }); + } + + async getImage(filename: string) { + const buffer = await this.OPFS.readFrom(filename, ImageStorage.IMAGES_DIR); + const mimeType = this.filetypeUtils.getImageMimeTypeFromFilename(filename); + return new Blob([buffer], { type: mimeType }); + } + + async getImageURL(filename: string) { + const blob = await this.getImage(filename); + return URL.createObjectURL(blob); + } + + async deleteImage(filename: string) { + this.OPFS.delete(filename, ImageStorage.IMAGES_DIR); + } +}