Node.jsライブラリsharpを使って2枚を1枚の画像に合成・圧縮する自動化mjsを作る
やりたいこと
パッケージのインストール
npm i sharp path fs
構成
├ 📁 images
│ └ 📁 convert
│ └ 📁 dir1
│ └ 📁 dir2
├ convertImages.mjs
├ package.json
convertImages.mjs
import fs from "fs/promises";
import path from "path";
import sharp from "sharp";
const __dirname = path.resolve();
const inputDir1Path = path.join(__dirname, 'images', 'dir1');
const inputDir2Path = path.join(__dirname, 'images', 'dir2');
const outputConvertPath = path.join(__dirname, 'images', 'convert');
const dir1Images = [];
const dir2Images = [];
async function readDir1Files() {
try {
const dir1Files = await fs.readdir(inputDir1Path);
dir1Images.push(...dir1Files.map(file => path.join(inputDir1Path, file)));
} catch (err) {
console.error('Error reading Dir1 folder:', err);
}
}
async function readDir2Files() {
try {
const dir2Files = await fs.readdir(inputDir2Path);
dir2Images.push(...dir2Files.map(file => path.join(inputDir2Path, file)));
} catch (err) {
console.error('Error reading Dir2 folder:', err);
}
}
async function convertImgs(dir1Images, dir2Images) {
for (let index = 0; index < dir1Images.length; index++) {
const dir1ImagePath = dir1Images[index];
const dir2ImagePath = dir2Images[index];
//Dir1->image info
const dir1ImageInfo = await sharp(dir1ImagePath).metadata();
const dir1ImgWidth = dir1ImageInfo.width;
const dir1ImgHeight = dir1ImageInfo.height;
//Dir2->image info
const dir2ImageInfo = await sharp(dir2ImagePath).metadata();
const dir2ImgWidth = dir2ImageInfo.width;
const dir2ImgHeight = dir2ImageInfo.height;
const convertWidth = dir1ImgWidth + dir2ImgWidth + 100; //100は、画像と画像の間分
const convertHeight = Math.max(dir1ImgHeight, dir2ImgHeight); //画像の高さを比較し高いサイズを採用->生成する画像の高さになる
const convertFilePath = dir1ImagePath.replace(/.(jpeg|png)/g, '.jpg'); //強制的に拡張子をjpgに置き換え
await sharp({ create: { width: convertWidth, height: convertHeight, channels: 4, background: { r: 255, g: 255, b: 255, alpha: 1 } } }) //背景を黒にする場合は、alpha: 0
.jpeg({
quality: 50, //圧縮 品質を50に設定
progressive: true
})
.composite([
{
input: dir1ImagePath,
left: 0,
top: 0,
gravity: 'northwest'
},
{
input: dir2ImagePath,
left: dir1ImgWidth + 100, // 1枚目との間を100px空ける
top: 0,
gravity: 'northeast'
}
])
.toFile(path.join(outputConvertPath, path.basename(convertFilePath))); //合成したファイル名
}
}
async function main() {
await readDir1Files();
await readDir2Files();
await convertImgs(dir1Images, dir2Images);
console.log('Images conversion complete.');
}
main().catch(error => {
console.error('Error:', error);
});
node convertImages.mjs
実行すると画像が生成されました!