Changed thumbnail function to produce square images

This commit is contained in:
Mitchell McCaffrey 2021-02-19 09:13:25 +11:00
parent a718eb20c6
commit 0a12361b16
2 changed files with 84 additions and 24 deletions

View File

@ -1,3 +1,7 @@
/**
* @param {Blob} blob
* @returns {Promise<Uint8Array>}
*/
async function blobToBuffer(blob) {
if (blob.arrayBuffer) {
const arrayBuffer = await blob.arrayBuffer();

View File

@ -38,18 +38,36 @@ export function getImageLightness(image) {
}
/**
* @typedef ResizedImage
* @typedef CanvasImage
* @property {Blob|null} blob The blob of the resized image, `null` if the image was unable to be resized to that dimension
* @property {number} width
* @property {number} height
*/
/**
* @param {HTMLCanvasElement} canvas
* @param {string} type
* @param {number} quality
* @returns {Promise<CanvasImage>}
*/
export async function canvasToImage(canvas, type, quality) {
return new Promise((resolve) => {
canvas.toBlob(
(blob) => {
resolve({ blob, width: canvas.width, height: canvas.height });
},
type,
quality
);
});
}
/**
* @param {HTMLImageElement} image the image to resize
* @param {number} size the size of the longest edge of the new image
* @param {string} type the mime type of the image
* @param {number} quality if image is a jpeg or webp this is the quality setting
* @returns {Promise<ResizedImage>}
* @returns {Promise<CanvasImage>}
*/
export async function resizeImage(image, size, type, quality) {
const width = image.width;
@ -66,30 +84,68 @@ export async function resizeImage(image, size, type, quality) {
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, canvas.width, canvas.height);
return new Promise((resolve) => {
canvas.toBlob(
(blob) => {
resolve({ blob, width: canvas.width, height: canvas.height });
},
type,
quality
);
});
return await canvasToImage(canvas, type, quality);
}
export async function createThumbnail(
image,
type,
resolution = 300,
quality = 0.5
) {
const thumbnailImage = await resizeImage(
image,
Math.min(resolution, image.width, image.height),
type,
quality
);
const thumbnailBuffer = await blobToBuffer(thumbnailImage.blob);
/**
* @typedef ImageFile
* @property {Uint8Array|null} file
* @property {number} width
* @property {number} height
* @property {"file"} type
* @property {string} id
*/
/**
* Create a image file with resolution `size`x`size` with cover cropping
* @param {HTMLImageElement} image the image to resize
* @param {string} type the mime type of the image
* @param {number} size the width and height of the thumbnail
* @param {number} quality if image is a jpeg or webp this is the quality setting
* @returns {Promise<ImageFile>}
*/
export async function createThumbnail(image, type, size = 300, quality = 0.5) {
let canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
let context = canvas.getContext("2d");
const ratio = image.width / image.height;
if (ratio > 1) {
const center = image.width / 2;
const halfHeight = image.height / 2;
context.drawImage(
image,
center - halfHeight,
0,
image.height,
image.height,
0,
0,
canvas.width,
canvas.height
);
} else {
const center = image.height / 2;
const halfWidth = image.width / 2;
context.drawImage(
image,
0,
center - halfWidth,
image.width,
image.width,
0,
0,
canvas.width,
canvas.height
);
}
const thumbnailImage = await canvasToImage(canvas, type, quality);
let thumbnailBuffer = null;
if (thumbnailImage.blob) {
thumbnailBuffer = await blobToBuffer(thumbnailImage.blob);
}
return {
file: thumbnailBuffer,
width: thumbnailImage.width,