feat: service to store images with OPFS
This commit is contained in:
75
src/app/services/image-storage.spec.ts
Normal file
75
src/app/services/image-storage.spec.ts
Normal file
File diff suppressed because one or more lines are too long
61
src/app/services/image-storage.ts
Normal file
61
src/app/services/image-storage.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user