// Name: Contact Sheet // Description: Creates a contact sheet from images in a dir // Author: tayiorbeii import Jimp from 'jimp'; // Pick directory of images const dirPath = await path({ onlyDirs: true, placeholder: "Pick a directory of images" }); // Read files from directory let files: string[]; try { files = await readdir(dirPath); } catch (error) { console.error("Error reading directory:", error); await div("Error reading directory. Check console."); exit(); } // Filter for image files (jpg, jpeg, png, gif) const imageFiles = files.filter(file => /\.(jpe?g|png|gif)$/i.test(file)); // Check if images were found if (imageFiles.length === 0) { await div("No images found in the selected directory."); exit(); } // Read images using Jimp let images = await Promise.all(imageFiles.map(async file => { try { return await Jimp.read(path.join(dirPath, file)); } catch (error) { console.error(`Error reading ${file}:`, error); return null; // Return null for failed images, filter later. } })); // Filter out null images (failed reads) images = images.filter(image => image !== null) as Jimp[]; // Configuration const thumbSize = 200; const padding = 20; const imagesPerRow = 5; const rows = Math.ceil(images.length / imagesPerRow); // Calculate composite dimensions const compositeWidth = imagesPerRow * (thumbSize + padding) + padding; const compositeHeight = rows * (thumbSize + padding) + padding; // Create composite image const composite = new Jimp(compositeWidth, compositeHeight, 0xFFFFFFFF); // Loop through and composite images for (let i = 0; i < images.length; i++) { const row = Math.floor(i / imagesPerRow); const col = i % imagesPerRow; const x = padding + col * (thumbSize + padding); const y = padding + row * (thumbSize + padding); images[i].scaleToFit(thumbSize, thumbSize); composite.composite(images[i], x, y); } // Output name const outputName = path.join(dirPath, `contact-sheet-${Date.now()}.png`); // Write the composite image try { await composite.writeAsync(outputName); } catch (error) { console.error("Error writing composite image:", error); await div("Error writing image. Check console."); exit(); } // Show success message and open file await div(md(`## Contact Sheet Created!`), { onInit: async () => { open(outputName); } });