From b5e7b83f229d6251f7bff6c65fbb1aed488739af Mon Sep 17 00:00:00 2001 From: LCJ-MinYa <1049468118@qq.com> Date: Mon, 30 Sep 2024 16:20:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E8=AF=9D=E8=A3=81?= =?UTF-8?q?=E5=89=AA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/index.js | 36 ++++++++++++++++ index.js | 91 ---------------------------------------- package.json | 25 +++++------ src/product_cover_img.js | 63 ++++++++++++++++++++++++++++ utils/index.js | 44 +++++++++++++++++++ 5 files changed, 156 insertions(+), 103 deletions(-) create mode 100644 config/index.js delete mode 100644 index.js create mode 100644 src/product_cover_img.js create mode 100644 utils/index.js diff --git a/config/index.js b/config/index.js new file mode 100644 index 0000000..f574ed6 --- /dev/null +++ b/config/index.js @@ -0,0 +1,36 @@ +const config = { + //基础公共配置 + base: { + // 指定要查找的目录 + directoryPath: '/Users/minya/Desktop/商品资料', + /** + * 图片文件夹路径 + * 1. 配置文件中inputDir为空 + * 则根据directoryPath目录获取该文件夹下最新创建的文件夹作为工作目录 + * + * 2. 配置文件中inputDir不为空 + * 则直接使用inputDir作为工作目录 + */ + inputDir: '', + }, + // 裁剪商品封面图 + cover: { + // 支持处理的常见图片格式 + imgFormat: new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'svg']), + // 封面图裁剪比例 + scaleArr: [ + { + name: '主图1:1', + scale: [1, 1], + dir: '', + }, + { + name: '主图3:4', + scale: [3, 4], + dir: '', + }, + ], + }, +}; + +module.exports = config; diff --git a/index.js b/index.js deleted file mode 100644 index 1e7d676..0000000 --- a/index.js +++ /dev/null @@ -1,91 +0,0 @@ -const sharp = require('sharp'); -const fs = require('fs'); -const path = require('path'); - -// 常见图片格式 -const imageExtensions = new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'svg']); -//图片文件夹路径 -let inputDir = ''; -//输出比例 -const outputArr = [ - { - name: '主图1:1', - scale: [1, 1], - dir: '', - }, - { - name: '主图3:4', - scale: [3, 4], - dir: '', - }, -]; -// 指定要查找的目录 -const directoryPath = 'E:/商品资料'; - -// 函数获取最新创建的子文件夹路径 -function getLatestFolder(directory) { - let latestTime = 0; - - // 读取指定目录 - fs.readdirSync(directory, { withFileTypes: true }).forEach((file) => { - if (file.isDirectory()) { - const folderPath = path.join(directory, file.name); - const stats = fs.statSync(folderPath); - const creationTime = stats.birthtimeMs; // 获取创建时间 - - // 找到最新创建的文件夹 - if (creationTime > latestTime) { - latestTime = creationTime; - inputDir = folderPath; - } - } - }); - - if (inputDir) { - console.log('最新创建的文件夹路径:', inputDir); - } else { - console.log('没有找到子文件夹。'); - } -} - -// 调用函数 -getLatestFolder(directoryPath); - -//创建输出文件夹 -outputArr.forEach((item) => { - item.dir = `${inputDir}/${item.scale.join('x')}`; - if (!fs.existsSync(item.dir)) { - fs.mkdirSync(item.dir); - } -}); - -async function resizeImage(imageDir, outputDir, scale) { - let imgData = await sharp(imageDir).metadata(); - await sharp(imageDir) - .extract({ - width: imgData.width, - height: Math.floor(imgData.width / (scale[0] / scale[1])), - left: 0, - top: 0, - }) - .toFile(outputDir); -} - -//读取输入目录下所有文件 -fs.readdirSync(inputDir).forEach(async (file) => { - console.log(file); - const ext = file.split('.').pop().toLowerCase(); - if (imageExtensions.has(ext)) { - const inputPath = path.join(inputDir, file); - outputArr.forEach((item) => { - const outputPath = path.join(item.dir, file); - resizeImage(inputPath, outputPath, item.scale) - .then(() => { - console.log(`${file}的${item.name}图片已生成`); - }) - .catch((err) => { - console.error(`${file}的${item.name}图片生成失败`, err); - }); - }); - } -}); diff --git a/package.json b/package.json index e821000..a4be03d 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,15 @@ { - "name": "sharp_img", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "sharp": "^0.33.5" - } + "name": "sharp_img", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "cover": "node ./src/product_cover_img.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "sharp": "^0.33.5" + } } diff --git a/src/product_cover_img.js b/src/product_cover_img.js new file mode 100644 index 0000000..b3d3691 --- /dev/null +++ b/src/product_cover_img.js @@ -0,0 +1,63 @@ +const sharp = require('sharp'); +const fs = require('fs'); +const path = require('path'); +const { getInputDir } = require('../utils/index'); +const { cover } = require('../config/index'); + +//图片文件夹路径 +let inputDir = getInputDir(); + +if (!inputDir) { + console.log('未执行裁剪主图,工作目录不存在'); + return; +} + +//创建输出文件夹 +cover.scaleArr.forEach((item) => { + item.dir = `${inputDir}/${item.scale.join('x')}`; + if (!fs.existsSync(item.dir)) { + fs.mkdirSync(item.dir); + } +}); + +async function resizeImage(imageDir, outputDir, scale) { + let imgData = await sharp(imageDir).metadata(); + let config = { + width: 0, + height: 0, + }; + if (imgData.height / scale[1] > imgData.width / scale[0]) { + config.width = imgData.width; + config.height = Math.floor(imgData.width / (scale[0] / scale[1])); + config.top = 0; + config.left = 0; + await sharp(imageDir).extract(config).toFile(outputDir); + } else { + config.width = imgData.height; + config.height = Math.floor(imgData.height / (scale[0] / scale[1])); + await sharp(imageDir) + .resize(config.width, config.height, { + fit: 'cover', + position: 'center', + }) + .toFile(outputDir); + } +} + +//读取输入目录下所有文件 +fs.readdirSync(inputDir).forEach(async (file) => { + const ext = file.split('.').pop().toLowerCase(); + if (cover.imgFormat.has(ext)) { + const inputPath = path.join(inputDir, file); + cover.scaleArr.forEach((item) => { + const outputPath = path.join(item.dir, file); + resizeImage(inputPath, outputPath, item.scale) + .then(() => { + console.log(`${file}的${item.name}图片已生成`); + }) + .catch((err) => { + console.error(`${file}的${item.name}图片生成失败`, err); + }); + }); + } +}); diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..0fd7fc6 --- /dev/null +++ b/utils/index.js @@ -0,0 +1,44 @@ +const fs = require('fs'); +const path = require('path'); +const { base } = require('../config/index'); + +// 获取最终工作目录 +const getInputDir = () => { + if (base.inputDir) { + return base.inputDir; + } + + base.inputDir = getLatestFolder(base.directoryPath); + return base.inputDir; +}; + +// 获取该文件夹下最新创建的文件夹作为工作目录 +const getLatestFolder = (directory) => { + let currentInputDir = null; + + // 读取指定目录 + fs.readdirSync(directory, { withFileTypes: true }).forEach((file) => { + if (file.isDirectory()) { + const folderPath = path.join(directory, file.name); + const stats = fs.statSync(folderPath); + const creationTime = stats.birthtimeMs; // 获取创建时间 + + // 找到最新创建的文件夹 + let latestTime = 0; + if (creationTime > latestTime) { + latestTime = creationTime; + currentInputDir = folderPath; + } + } + }); + + if (currentInputDir) { + console.log('工作目录:', currentInputDir); + } else { + console.log('未找到工作目录.'); + } + + return currentInputDir; +}; + +module.exports = { getInputDir, getLatestFolder };