mirror of
https://github.com/slynn1324/tinypin
synced 2025-12-12 06:15:35 +00:00
113 lines
3.9 KiB
JavaScript
113 lines
3.9 KiB
JavaScript
const sharp = require('sharp');
|
|
const fetch = require('node-fetch');
|
|
const fs = require('fs').promises;
|
|
const conf = require("./conf.js");
|
|
|
|
const THUMBNAIL_IMAGE_SIZE = 400;
|
|
const ADDITIONAL_IMAGE_SIZES = [800,1280,1920,2560];
|
|
|
|
/**
|
|
* Downloads the image, converts it to JPG, and creates the thumbnail size so that standard dimensions can be taken
|
|
* @param {string} imageUrl
|
|
*/
|
|
async function downloadImage(imageUrl){
|
|
|
|
let res = await fetch(imageUrl);
|
|
|
|
if ( res.status != 200 ){
|
|
throw(new Error(`download error status=${res.status}`));
|
|
}
|
|
|
|
let buffer = await res.buffer();
|
|
|
|
return await processImage(buffer);
|
|
}
|
|
|
|
async function processImage(buffer){
|
|
let original = sharp(buffer);
|
|
let originalBuffer = await original.toFormat("jpg").toBuffer();
|
|
let originalMetadata = await original.metadata();
|
|
|
|
let thumbnail = await original.resize({ width: THUMBNAIL_IMAGE_SIZE, height: THUMBNAIL_IMAGE_SIZE, fit: 'inside' });
|
|
let thumbnailBuffer = await thumbnail.toBuffer();
|
|
let thumbnailMetadata = await sharp(thumbnailBuffer).metadata();
|
|
|
|
return {
|
|
original: {
|
|
buffer: originalBuffer,
|
|
width: originalMetadata.width,
|
|
height: originalMetadata.height
|
|
},
|
|
thumbnail: {
|
|
buffer: thumbnailBuffer,
|
|
width: thumbnailMetadata.width,
|
|
height: thumbnailMetadata.height
|
|
}
|
|
}
|
|
}
|
|
|
|
// takes the response from downloadImage, creates ADDITIONAL_IMAGE_SIZE and writes all files to disk
|
|
async function saveImage(userId, pinId, image){
|
|
let originalImagePath = getImagePath(userId, pinId, 'o');
|
|
await fs.mkdir(originalImagePath.dir, {recursive: true});
|
|
await fs.writeFile(originalImagePath.file, image.original.buffer);
|
|
console.log(`saved original to: ${originalImagePath.file}`);
|
|
|
|
let thumbnailImagePath = getImagePath(userId, pinId, '400');
|
|
await fs.mkdir(thumbnailImagePath.dir, {recursive: true});
|
|
await fs.writeFile(thumbnailImagePath.file, image.thumbnail.buffer);
|
|
console.log(`saved thumbnail to: ${thumbnailImagePath.file}`);
|
|
|
|
// this will enlarge images if necessary, as the lanczos3 resize algorithm will create better looking enlargements than the browser will
|
|
for ( let i = 0; i < ADDITIONAL_IMAGE_SIZES.length; ++i ){
|
|
let size = ADDITIONAL_IMAGE_SIZES[i];
|
|
|
|
let img = await sharp(image.original.buffer);
|
|
let resizedImg = await img.resize({width: size, height: size, fit: 'inside'})
|
|
let buf = await resizedImg.toBuffer();
|
|
|
|
let imgPath = getImagePath(userId, pinId, size);
|
|
await fs.mkdir(imgPath.dir, {recursive:true});
|
|
await fs.writeFile(imgPath.file, buf);
|
|
console.log(`saved additional size ${size} to: ${imgPath.file}`);
|
|
}
|
|
}
|
|
|
|
async function deleteImagesForPin(userId, pinId){
|
|
console.log("deleting images for userId=" + userId + " pinId=" + pinId);
|
|
|
|
try {
|
|
await fs.unlink(getImagePath(userId, pinId, 'o').file);
|
|
} catch (err){
|
|
console.log("error deleting original: ", err);
|
|
}
|
|
|
|
try {
|
|
await fs.unlink(getImagePath(userId, pinId, THUMBNAIL_IMAGE_SIZE).file);
|
|
} catch (err){
|
|
console.log("error deleting thumbnail: " + err);
|
|
}
|
|
|
|
for ( let s = 0; s < ADDITIONAL_IMAGE_SIZES.length; ++s ){
|
|
try{
|
|
await fs.unlink(getImagePath(userId, pinId, ADDITIONAL_IMAGE_SIZES[s]).file);
|
|
} catch (err){
|
|
console.log("error deleting additional size " + ADDITIONAL_IMAGE_SIZES[s] + ": ", err);
|
|
}
|
|
}
|
|
}
|
|
|
|
function getImagePath(userId, pinId, size){
|
|
let paddedId = pinId.toString().padStart(12, '0');
|
|
let dir = `${conf.getImagePath()}/${userId}/images/${size}/${paddedId[11]}/${paddedId[10]}/${paddedId[9]}/${paddedId[8]}`;
|
|
let file = `${dir}/${paddedId}.jpg`;
|
|
return { dir: dir, file: file};
|
|
}
|
|
|
|
module.exports = {
|
|
processImage: processImage,
|
|
saveImage: saveImage,
|
|
getImagePath: getImagePath,
|
|
downloadImage: downloadImage,
|
|
deleteImagesForPin: deleteImagesForPin
|
|
} |