feat: service to store images with OPFS

This commit is contained in:
2026-02-06 21:41:20 -03:00
parent c0a3da4635
commit e803c670f4
2 changed files with 136 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@@ -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<Blob> {
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);
}
}