portfolio/packages/gallery/src/context/generateThumbnails.js
2017-10-30 04:41:58 -05:00

73 lines
1.8 KiB
JavaScript

import pica from 'pica/dist/pica';
import { generateAttachmentUrl, getDatabase } from '../services/db.js';
import { find, update, addAttachment } from '../data/image.js';
export function maxLinearSize(width, height, max) {
const ratio = width / height;
if (width > height) {
return {
width: max,
height: max / ratio
};
}
return {
width: max * ratio,
height: max
};
}
async function getLoadedImage(src) {
return new Promise(resolve => {
const i = new Image('image');
i.onload = () => resolve(i);
i.src = src;
});
}
async function resizeImage(imageBlob, mimetype, width, height) {
const url = URL.createObjectURL(imageBlob);
const $img = await getLoadedImage(url);
const $destinationCanvas = document.createElement('canvas');
$destinationCanvas.width = width;
$destinationCanvas.height = height;
const afterResize = (resolve, reject) => err => {
if (err) {
return reject(err);
}
$destinationCanvas.toBlob(resolve, mimetype);
};
return new Promise((resolve, reject) => {
pica.resizeCanvas($img, $destinationCanvas, {}, afterResize(resolve, reject));
});
}
export async function generateThumbnailForImage(id) {
const results = await find([id], { attachments: true, binary: true });
const doc = results.rows[0].doc;
if (doc.attachmentUrls.thumbnail && doc._attachments.thumbnail) {
return;
}
const attachment = doc._attachments.image;
const mimetype = attachment.content_type;
const { width, height } = maxLinearSize(doc.width, doc.height, 320);
const resizedBlob = await resizeImage(attachment.data, mimetype, width, height);
const url = generateAttachmentUrl(getDatabase().name, id, 'thumbnail');
await addAttachment(doc, 'thumbnail', resizedBlob);
await update(doc._id, {
attachmentUrls: {
thumbnail: url
}
});
return resizedBlob;
}
export const invoke = generateThumbnailForImage;