fix: 先检查 output 跳过已处理项目再开始处理
This commit is contained in:
+46
-15
@@ -11,11 +11,20 @@ const {
|
|||||||
IMAGE_TYPE_LABELS,
|
IMAGE_TYPE_LABELS,
|
||||||
} = require('./utils');
|
} = require('./utils');
|
||||||
|
|
||||||
// 处理单个图片
|
// 输出可能是 .jpg 或 .webp,先按文件名探测是否已处理,避免读 EXIF
|
||||||
function processImage(inputPath, outputPath) {
|
function findExistingOutput(targetDir, inputFilename) {
|
||||||
|
const base = path.basename(inputFilename, path.extname(inputFilename));
|
||||||
|
const candidates = ['.jpg', '.webp'].map((ext) => path.join(targetDir, base + ext));
|
||||||
|
return candidates.find((p) => fs.existsSync(p)) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理单个图片(可传入预检测结果,避免重复 identify / exiftool)
|
||||||
|
function processImage(inputPath, outputPath, predetect) {
|
||||||
const filename = path.basename(inputPath);
|
const filename = path.basename(inputPath);
|
||||||
const dimensions = getImageDimensions(inputPath);
|
const dimensions = predetect?.dimensions ?? getImageDimensions(inputPath);
|
||||||
const { type, reason } = detectImageType(inputPath, dimensions);
|
const { type, reason } = predetect
|
||||||
|
? { type: predetect.type, reason: predetect.reason }
|
||||||
|
: detectImageType(inputPath, dimensions);
|
||||||
const outputExt = getOutputExtension(type);
|
const outputExt = getOutputExtension(type);
|
||||||
const newFilename = path.basename(outputPath, path.extname(outputPath)) + outputExt;
|
const newFilename = path.basename(outputPath, path.extname(outputPath)) + outputExt;
|
||||||
const finalOutputPath = path.join(path.dirname(outputPath), newFilename);
|
const finalOutputPath = path.join(path.dirname(outputPath), newFilename);
|
||||||
@@ -103,12 +112,36 @@ async function runFormatTool(rl) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`\n📋 找到 ${files.length} 个文件:`);
|
console.log(`\n📋 源目录共 ${files.length} 个文件,先检查 output 中已存在的结果...`);
|
||||||
files.forEach((file, index) => {
|
|
||||||
|
const pendingFiles = [];
|
||||||
|
let skipped = 0;
|
||||||
|
for (const file of files) {
|
||||||
|
const existing = findExistingOutput(targetDir, file);
|
||||||
|
if (existing) {
|
||||||
|
skipped++;
|
||||||
|
console.log(` ⏭️ ${file} → 已存在 ${path.basename(existing)}`);
|
||||||
|
} else {
|
||||||
|
pendingFiles.push(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pendingFiles.length === 0) {
|
||||||
|
console.log(`\n✅ 全部 ${files.length} 个文件已在输出目录中,无需处理`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n🔍 分析剩余 ${pendingFiles.length} 个文件的相机/类型(已跳过 ${skipped} 个)...`);
|
||||||
|
const jobs = pendingFiles.map((file) => {
|
||||||
const inputPath = path.join(sourceDir, file);
|
const inputPath = path.join(sourceDir, file);
|
||||||
const dimensions = getImageDimensions(inputPath);
|
const dimensions = getImageDimensions(inputPath);
|
||||||
const { type, reason } = detectImageType(inputPath, dimensions);
|
const { type, reason } = detectImageType(inputPath, dimensions);
|
||||||
console.log(` ${index + 1}. ${file} → ${IMAGE_TYPE_LABELS[type]} (${reason})`);
|
return { file, inputPath, dimensions, type, reason };
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`\n📋 待处理 ${jobs.length} 个文件:`);
|
||||||
|
jobs.forEach((job, index) => {
|
||||||
|
console.log(` ${index + 1}. ${job.file} → ${IMAGE_TYPE_LABELS[job.type]} (${job.reason})`);
|
||||||
});
|
});
|
||||||
|
|
||||||
const confirm = await question(rl, '\n❓ 是否开始处理? (y/n): ');
|
const confirm = await question(rl, '\n❓ 是否开始处理? (y/n): ');
|
||||||
@@ -119,24 +152,22 @@ async function runFormatTool(rl) {
|
|||||||
|
|
||||||
console.log('\n🚀 开始处理...\n');
|
console.log('\n🚀 开始处理...\n');
|
||||||
let processed = 0;
|
let processed = 0;
|
||||||
let skipped = 0;
|
|
||||||
let failed = 0;
|
let failed = 0;
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < jobs.length; i++) {
|
||||||
const file = files[i];
|
const job = jobs[i];
|
||||||
const inputPath = path.join(sourceDir, file);
|
const outputPath = path.join(targetDir, job.file);
|
||||||
const outputPath = path.join(targetDir, file);
|
|
||||||
|
|
||||||
console.log(`\n[${i + 1}/${files.length}]`);
|
console.log(`\n[${i + 1}/${jobs.length}]`);
|
||||||
try {
|
try {
|
||||||
const result = processImage(inputPath, outputPath);
|
const result = processImage(job.inputPath, outputPath, job);
|
||||||
if (result) {
|
if (result) {
|
||||||
processed++;
|
processed++;
|
||||||
} else {
|
} else {
|
||||||
skipped++;
|
skipped++;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ 处理失败: ${file}`);
|
console.error(`❌ 处理失败: ${job.file}`);
|
||||||
failed++;
|
failed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user