@self.id/image-utils
Version:
Image utilities for Self.ID profiles
69 lines (68 loc) • 2.37 kB
JavaScript
import Pica from 'pica';
import { uploadFile } from './ipfs.js';
import { getDimensions } from './selection.js';
const pica = new Pica();
/** Load a `blob` image to an HTML Image element. */ export async function loadImage(blob) {
return new Promise((resolve, reject)=>{
function onError() {
reject(new Error('Failed to load image'));
}
const image = new Image();
image.onerror = onError;
image.onload = function() {
resolve(image);
};
const reader = new FileReader();
reader.onerror = onError;
reader.onload = function(readerEvent) {
if (readerEvent.target?.result == null) {
onError();
} else {
image.src = readerEvent.target.result;
}
};
reader.readAsDataURL(blob);
});
}
/** @internal */ export async function resizeImageElement(type, image, dimensions, mode) {
const { width , height } = getDimensions(image, dimensions, mode);
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const res = await pica.resize(image, canvas);
return {
blob: await pica.toBlob(res, type),
height,
width
};
}
/** Resize an image and upload it to IPFS. */ export async function uploadResizedImage(url, type, image, dimensions) {
const { blob , height , width } = await resizeImageElement(type, image, dimensions);
const hash = await uploadFile(url, blob);
return {
src: 'ipfs://' + hash,
height,
width,
mimeType: blob.type,
size: blob.size
};
}
/** Upload an image to IPFS, optionally with additional alternative `sizes`. */ export async function uploadImage(url, file, sizes = []) {
const image = await loadImage(file);
const uploadAlternatives = Promise.all(sizes.map(async (dimensions)=>await uploadResizedImage(url, file.type, image, dimensions)
));
const [originalHash, alternatives] = await Promise.all([
uploadFile(url, file),
uploadAlternatives,
]);
return {
alternatives,
original: {
src: 'ipfs://' + originalHash,
height: image.height,
width: image.width,
mimeType: file.type,
size: file.size
}
};
}