feat: ppt转图片

main
lichaojun 1 year ago
parent f3ebfa3a4e
commit 6b209f3209

@ -2,7 +2,7 @@ const config = {
//基础公共配置
base: {
// 指定要查找的目录
directoryPath: '/Users/minya/Desktop/商品资料',
directoryPath: 'C:/Users/Administrator/Desktop/test',
/**
* 图片文件夹路径
* 1. 配置文件中inputDir为空
@ -16,7 +16,7 @@ const config = {
// 裁剪商品封面图
cover: {
// 支持处理的常见图片格式
format: new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'svg']),
imgFormat: new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'svg']),
// 封面图裁剪比例
scaleArr: [
{
@ -32,8 +32,8 @@ const config = {
],
},
ppt: {
// 支持处理的常见图片格式
format: new Set(['ppt', 'pptx']),
pptFormat: new Set(['ppt', 'pptx']),
pdfFormat: new Set(['pdf']),
},
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

@ -0,0 +1,85 @@
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');
/**
* 拼接图片
* @param {Array<string>} imagePaths - 图片路径数组
* @param {number} num - 每行显示的图片数量
* @param {string} bgColor - 背景颜色例如'#ffffff'
* @param {number} width - 拼接后的宽度
* @param {number} gap - 图片之间的间隙
*/
async function stitchImages(imagePaths, num, bgColor, width, gap) {
// 获取第一张图片的信息
const firstImageInfo = await sharp(imagePaths[0]).metadata();
const firstImageHeight = Math.floor((firstImageInfo.height / firstImageInfo.width) * width); // 根据比例计算高度
// 处理剩余的图片
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' })
.toBuffer({ resolveWithObject: true });
return { data, height: info.height }; // 返回图片数据及其高度
})
);
const rows = Math.ceil(remainingImagesInfo.length / num); // 计算剩余图片的行数
const totalHeight = firstImageHeight + (remainingImagesInfo[0]?.height + gap) * rows + gap; // 总高度
const totalWidth = width + 2 * gap; // 总宽度,包括外层间隙
// 创建拼接后的图片
const outputImage = await sharp({
create: {
width: totalWidth,
height: totalHeight,
channels: 3,
background: bgColor,
},
})
.composite([
{
input: await sharp(imagePaths[0]).resize(width, firstImageHeight).toBuffer(),
top: gap, // 第一张图片顶部留出外层间隙
left: gap, // 第一张图片左侧留出外层间隙
},
...remainingImagesInfo.map((imgInfo, index) => {
const row = Math.floor(index / num);
const col = index % num;
return {
input: imgInfo.data,
top: firstImageHeight + gap + row * (imgInfo.height + gap), // 计算纵向位置
left: gap + Math.floor(col * (width / num) + col * gap), // 计算横向位置并取整
};
}),
])
.toFile('output.png');
console.log('拼接完成,输出文件为:', outputImage);
}
// 示例使用
const num = 2; // 每行显示的图片数量
const bgColor = 'red'; // 背景颜色
const width = 1000; // 拼接后的宽度
const gap = 10; // 图片之间的间隙
stitchImages(imagePaths, num, bgColor, width, gap).catch((err) => console.error('发生错误:', err));

@ -1,11 +1,11 @@
const { exec } = require('child_process');
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const { getInputDir } = require('../utils/index');
const { ppt } = require('../config/index');
//工作目录文件夹路径
const inputDir = getInputDir(); // 输入PPT文件路径
const inputDir = getInputDir();
if (!inputDir) {
console.log('未执行ppt转图片功能工作目录不存在');
@ -25,47 +25,41 @@ if (!fs.existsSync(imgDir)) {
fs.mkdirSync(imgDir);
}
const convertPptToImages = (inputDir, outputDir) => {
// 使用 LibreOffice 将 PPT 转换为 PDF
// const pdfFilePath = path.join(outputDir, '9.pdf');
// console.log(pdfFilePath);
const convertCommand = `soffice --headless --invisible --convert-to pdf --outdir "${outputDir}" "${inputDir}"`;
const convertPptToPdf = (inputDir) => {
const pdfCmd = `soffice --headless --invisible --convert-to pdf --outdir "${pdfDir}" "${inputDir}" 2>NUL`;
console.log(pdfCmd);
return new Promise((resolve, reject) => {
exec(convertCommand, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
execSync(pdfCmd);
};
// // 使用 ImageMagick 将 PDF 转换为图片
// const imageOutputPath = path.join(outputDir, 'slide_%d.png');
// const convertImageCommand = `convert -density 300 "${pdfFilePath}" "${imageOutputPath}"`;
// 使用 ImageMagick 将 PDF 转换为图片
const convertPdfToImg = (inputDir, file) => {
const imgItemDir = path.join(imgDir, `${file.split('.')[0]}`);
if (!fs.existsSync(imgItemDir)) {
fs.mkdirSync(imgItemDir);
}
// exec(convertImageCommand, (error) => {
// if (error) {
// console.error(`转换为图片失败: ${error}`);
// return;
// }
// console.log('转换成功!输出目录:', outputDir);
// });
});
});
const imageOutputPath = path.join(imgItemDir, 'slide_%d.png');
const imgCmd = `magick -density 72 "${inputDir}" "${imageOutputPath}"`;
console.log(imgCmd);
execSync(imgCmd);
};
//读取输入目录下所有文件
fs.readdirSync(inputDir).forEach(async (file) => {
// 读取输入目录下所有ppt文件 => 转换为pdf
fs.readdirSync(inputDir).forEach((file) => {
const ext = file.split('.').pop().toLowerCase();
if (ppt.format.has(ext)) {
if (ppt.pptFormat.has(ext)) {
const inputPath = path.join(inputDir, file);
const outputPath = path.join(pdfDir, file);
convertPptToImages(inputPath, outputPath)
.then(() => {
console.log(`${file}的图片已生成`);
})
.catch((err) => {
console.error(`${file}的图片生成失败`, err);
convertPptToPdf(inputPath);
}
});
// 读取输入目录下所有pdf文件下所有pdf文件 => 转换为image
fs.readdirSync(pdfDir).forEach((file) => {
const ext = file.split('.').pop().toLowerCase();
if (ppt.pdfFormat.has(ext)) {
const inputPath = path.join(pdfDir, file);
convertPdfToImg(inputPath, file);
}
});

@ -47,7 +47,7 @@ async function resizeImage(imageDir, outputDir, scale) {
//读取输入目录下所有文件
fs.readdirSync(inputDir).forEach(async (file) => {
const ext = file.split('.').pop().toLowerCase();
if (cover.format.has(ext)) {
if (cover.imgFormat.has(ext)) {
const inputPath = path.join(inputDir, file);
cover.scaleArr.forEach((item) => {
const outputPath = path.join(item.dir, file);

Loading…
Cancel
Save