diff --git a/config/index.js b/config/index.js index 0a530c8..42f68d1 100644 --- a/config/index.js +++ b/config/index.js @@ -35,6 +35,18 @@ const config = { pptFormat: new Set(['ppt', 'pptx']), pdfFormat: new Set(['pdf']), }, + merge: { + // 每行图片的个数 + row: 3, + //画布背景颜色 + bgColor: 'rgb(211, 211, 211)', + //画布宽度 + width: 1000, + //画布外边距 + margin: 3, + //图片间距 + padding: 3, + }, }; module.exports = config; diff --git a/package.json b/package.json index 5446457..78509df 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "cover": "node ./src/product_cover_img.js", - "ppt": "node ./src/ppt_to_img.js" + "ppt": "node ./src/ppt_to_img.js", + "merge": "node ./src/img_merge.js" }, "author": "", "license": "ISC", diff --git a/src/img_merge.js b/src/img_merge.js index 199d151..7981659 100644 --- a/src/img_merge.js +++ b/src/img_merge.js @@ -1,33 +1,31 @@ -const imagePaths = [ - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_0.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_1.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_2.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_3.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_4.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_5.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_6.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_7.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_8.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_9.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_10.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_11.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_12.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_13.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_14.png', - 'C:/Users/Administrator/Desktop/test/ppt1001/img/01/slide_15.png', -]; - const sharp = require('sharp'); +const fs = require('fs'); +const path = require('path'); +const { getInputDir } = require('../utils/index'); +const { merge, cover } = require('../config/index'); + +//工作目录文件夹路径 +const inputDir = getInputDir(); +if (!inputDir) { + console.log('未执行ppt拼图功能,工作目录不存在'); + return; +} + +//需要拼图的文件夹 +const merageImgDir = `${inputDir}/img`; +const pdfDir = `${inputDir}/pdf`; +if (!merageImgDir) { + console.log('未执行ppt拼图功能,工作目录下的图片文件夹不存在'); + return; +} -/** - * 拼接图片 - * @param {Array} imagePaths - 图片路径数组 - * @param {number} num - 每行显示的图片数量 - * @param {string} bgColor - 背景颜色(例如:'#ffffff') - * @param {number} width - 拼接后的宽度 - * @param {number} gap - 图片之间的间隙 - */ -async function stitchImages(imagePaths, num, bgColor, width, gap) { +//创建预览图输出文件夹 +const previewDir = `${inputDir}/预览图`; +if (!fs.existsSync(previewDir)) { + fs.mkdirSync(previewDir); +} + +async function stitchImages(imagePaths, { row, bgColor, width, margin, padding }, outputName) { // 获取第一张图片的信息 const firstImageInfo = await sharp(imagePaths[0]).metadata(); const firstImageHeight = Math.floor((firstImageInfo.height / firstImageInfo.width) * width); // 根据比例计算高度 @@ -36,15 +34,15 @@ async function stitchImages(imagePaths, num, bgColor, width, gap) { const remainingImagesInfo = await Promise.all( imagePaths.slice(1).map(async (imagePath) => { const { data, info } = await sharp(imagePath) - .resize({ width: Math.floor((width - gap * (num - 1)) / num), fit: 'inside' }) + .resize({ width: Math.floor((width - padding * 2 * row) / row), fit: 'inside' }) .toBuffer({ resolveWithObject: true }); - return { data, height: info.height }; // 返回图片数据及其高度 + return { data, info }; // 返回图片数据及其高度 }) ); - const rows = Math.ceil(remainingImagesInfo.length / num); // 计算剩余图片的行数 - const totalHeight = firstImageHeight + (remainingImagesInfo[0]?.height + gap) * rows + gap; // 总高度 - const totalWidth = width + 2 * gap; // 总宽度,包括外层间隙 + const rows = Math.ceil(remainingImagesInfo.length / row); // 计算剩余图片的行数 + const totalHeight = margin * 2 + (padding * 2 + firstImageHeight) + (remainingImagesInfo[0]?.info.height + padding * 2) * rows; // 总高度 + const totalWidth = width + 2 * margin; // 总宽度,包括外层间隙 // 创建拼接后的图片 const outputImage = await sharp({ @@ -57,29 +55,60 @@ async function stitchImages(imagePaths, num, bgColor, width, gap) { }) .composite([ { - input: await sharp(imagePaths[0]).resize(width, firstImageHeight).toBuffer(), - top: gap, // 第一张图片顶部留出外层间隙 - left: gap, // 第一张图片左侧留出外层间隙 + input: await sharp(imagePaths[0]) + .resize(width - 2 * padding, firstImageHeight) + .toBuffer(), + top: margin + padding, // 第一张图片顶部留出外层间隙 + left: margin + padding, // 第一张图片左侧留出外层间隙 }, - ...remainingImagesInfo.map((imgInfo, index) => { - const row = Math.floor(index / num); - const col = index % num; + ...remainingImagesInfo.map(({ data, info }, index) => { + const currentRow = Math.floor(index / row); + const currentCol = index % row; return { - input: imgInfo.data, - top: firstImageHeight + gap + row * (imgInfo.height + gap), // 计算纵向位置 - left: gap + Math.floor(col * (width / num) + col * gap), // 计算横向位置并取整 + input: data, + top: margin + padding + firstImageHeight + 2 * padding + currentRow * (info.height + padding * 2), // 计算纵向位置 + left: margin + padding + currentCol * padding * 2 + currentCol * info.width, // 计算横向位置并取整 }; }), ]) - .toFile('output.png'); + .toFile(outputName); - console.log('拼接完成,输出文件为:', outputImage); + console.log('拼接完成,输出文件为:', outputName); } -// 示例使用 -const num = 2; // 每行显示的图片数量 -const bgColor = 'red'; // 背景颜色 -const width = 1000; // 拼接后的宽度 -const gap = 10; // 图片之间的间隙 +const stitchPromises = []; // 存储所有拼图任务的 Promise +// 读取输入目录下所有文件夹,将每个文件夹内的图片拼图 +fs.readdirSync(merageImgDir, { withFileTypes: true }).forEach((imgDir) => { + if (imgDir.isDirectory()) { + const inputPath = path.join(merageImgDir, imgDir.name); + const imagePaths = []; + fs.readdirSync(inputPath).forEach((file) => { + const ext = file.split('.').pop().toLowerCase(); + if (cover.imgFormat.has(ext)) { + const imgPath = path.join(inputPath, file); + imagePaths.push(imgPath); + } + }); + const sortImagePaths = imagePaths.sort((a, b) => { + // 提取数字部分 + const numA = parseInt(a.match(/slide_(\d+)\.png/)[1], 10); + const numB = parseInt(b.match(/slide_(\d+)\.png/)[1], 10); -stitchImages(imagePaths, num, bgColor, width, gap).catch((err) => console.error('发生错误:', err)); + return numA - numB; // 按数字排序 + }); + const outputName = path.join(previewDir, `${imgDir.name}.png`); + stitchPromises.push(stitchImages(sortImagePaths, merge, outputName)); + } +}); + +// 等待所有拼图任务完成 +Promise.all(stitchPromises) + .then(() => { + console.log('所有拼图任务完成'); + fs.rmSync(merageImgDir, { recursive: true, force: true }); + fs.rmSync(pdfDir, { recursive: true, force: true }); + console.log('删除img和pdf文件夹任务完成'); + }) + .catch((err) => { + console.error('发生错误:', err); + }); diff --git a/src/ppt_to_img.js b/src/ppt_to_img.js index c09cd44..d68b626 100644 --- a/src/ppt_to_img.js +++ b/src/ppt_to_img.js @@ -14,7 +14,6 @@ if (!inputDir) { //创建pdf输出文件夹 const pdfDir = `${inputDir}/pdf`; -console.log(pdfDir); if (!fs.existsSync(pdfDir)) { fs.mkdirSync(pdfDir); }