fix: 增加索尼相机照片比例处理

This commit is contained in:
奇趣保罗 2026-07-03 16:13:30 +08:00
parent d277a6118f
commit e5dd163d22
4 changed files with 31 additions and 7 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"files.trimTrailingWhitespace": true
}

7
photo-toolkit.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
# 图片工具箱启动脚本
# 快速启动 photo-toolkit
cd "$(dirname "$0")/photo-toolkit"
node index.js

View File

@ -36,10 +36,13 @@ function processImage(inputPath, outputPath) {
{ stdio: 'inherit' } { stdio: 'inherit' }
); );
} else { } else {
const newSize = getTargetSize(type, dimensions.width, dimensions.height); const target = getTargetSize(type, dimensions.width, dimensions.height);
console.log(` 目标尺寸: ${newSize}`); console.log(` 目标尺寸: ${target.size}${target.crop ? '' : ' (保持比例)'}`);
const resizeArgs = target.crop
? `-gravity center -resize "${target.size}^" -extent "${target.size}"`
: `-resize "${target.size}"`;
execSync( execSync(
`magick "${inputPath}" -gravity center -resize "${newSize}^" -extent "${newSize}" -quality 80 "${finalOutputPath}"`, `magick "${inputPath}" ${resizeArgs} -quality 80 "${finalOutputPath}"`,
{ stdio: 'inherit' } { stdio: 'inherit' }
); );
} }
@ -67,7 +70,7 @@ function processImage(inputPath, outputPath) {
async function runFormatTool(rl) { async function runFormatTool(rl) {
console.log('\n🎨 图片格式转换工具'); console.log('\n🎨 图片格式转换工具');
console.log('='.repeat(50)); console.log('='.repeat(50));
console.log('支持类型: iPhone (4:3 JPG) · 索尼相机 (3:2 JPG) · 截图 (WebP)'); console.log('支持类型: iPhone (4:3 JPG) · 索尼相机 (3:2 JPG) · 截图 (WebP) · 小米手机 (4:3 JPG)');
const inputDir = await question(rl, '\n📁 请输入图片所在目录 (留空使用当前目录): '); const inputDir = await question(rl, '\n📁 请输入图片所在目录 (留空使用当前目录): ');
const sourceDir = inputDir.trim() || process.cwd(); const sourceDir = inputDir.trim() || process.cwd();

View File

@ -5,12 +5,14 @@ const readline = require('readline');
const IMAGE_TYPES = { const IMAGE_TYPES = {
IPHONE: 'iphone', IPHONE: 'iphone',
SONY: 'sony', SONY: 'sony',
XIAOMI: 'xiaomi',
SCREENSHOT: 'screenshot', SCREENSHOT: 'screenshot',
}; };
const IMAGE_TYPE_LABELS = { const IMAGE_TYPE_LABELS = {
[IMAGE_TYPES.IPHONE]: '📱 iPhone (4:3)', [IMAGE_TYPES.IPHONE]: '📱 iPhone (4:3)',
[IMAGE_TYPES.SONY]: '📷 索尼相机 (3:2)', [IMAGE_TYPES.SONY]: '📷 索尼相机 (3:2)',
[IMAGE_TYPES.XIAOMI]: '📱 小米手机 (4:3)',
[IMAGE_TYPES.SCREENSHOT]: '🖼️ 截图 → WebP', [IMAGE_TYPES.SCREENSHOT]: '🖼️ 截图 → WebP',
}; };
@ -72,14 +74,22 @@ function detectImageType(filePath, dimensions) {
const makeUpper = make.toUpperCase(); const makeUpper = make.toUpperCase();
const modelUpper = model.toUpperCase(); const modelUpper = model.toUpperCase();
// 我的 iPhone
if (makeUpper === 'APPLE' || modelUpper.includes('IPHONE')) { if (makeUpper === 'APPLE' || modelUpper.includes('IPHONE')) {
return { type: IMAGE_TYPES.IPHONE, reason: `EXIF: ${make} ${model}`.trim() }; return { type: IMAGE_TYPES.IPHONE, reason: `EXIF: ${make} ${model}`.trim() };
} }
// 老妈小米 11 青春版
if (makeUpper === 'XIAOMI' || modelUpper.includes('M2101K9C')) {
return { type: IMAGE_TYPES.XIAOMI, reason: `EXIF: ${make} ${model}`.trim() };
}
// 索尼相机
if (makeUpper.includes('SONY') || modelUpper.includes('ILCE') || modelUpper.startsWith('DSC-')) { if (makeUpper.includes('SONY') || modelUpper.includes('ILCE') || modelUpper.startsWith('DSC-')) {
return { type: IMAGE_TYPES.SONY, reason: `EXIF: ${make} ${model}`.trim() }; return { type: IMAGE_TYPES.SONY, reason: `EXIF: ${make} ${model}`.trim() };
} }
// iPhone
if (['.heic', '.heif'].includes(ext)) { if (['.heic', '.heif'].includes(ext)) {
return { type: IMAGE_TYPES.IPHONE, reason: 'HEIC/HEIF 格式' }; return { type: IMAGE_TYPES.IPHONE, reason: 'HEIC/HEIF 格式' };
} }
@ -90,18 +100,19 @@ function detectImageType(filePath, dimensions) {
} }
// 根据类型和方向获取目标尺寸,截图为 null不裁剪 // 根据类型和方向获取目标尺寸,截图为 null不裁剪
// 索尼返回 ImageMagick 缩放规格(如 2250x按原图宽高比缩放、不裁剪
function getTargetSize(type, width, height) { function getTargetSize(type, width, height) {
const landscape = width >= height; const landscape = width >= height;
switch (type) { switch (type) {
case IMAGE_TYPES.IPHONE: case IMAGE_TYPES.IPHONE:
return landscape ? '2000x1500' : '1500x2000'; return { size: landscape ? '2000x1500' : '1500x2000', crop: true };
case IMAGE_TYPES.SONY: case IMAGE_TYPES.SONY:
return landscape ? '2250x1500' : '1500x2250'; return { size: landscape ? '2250x' : 'x2250', crop: false };
case IMAGE_TYPES.SCREENSHOT: case IMAGE_TYPES.SCREENSHOT:
return null; return null;
default: default:
return landscape ? '2250x1500' : '1500x2250'; return { size: landscape ? '2250x1500' : '1500x2250', crop: true };
} }
} }