diff --git a/convert_and_copy_exif.sh b/convert_and_copy_exif.sh new file mode 100644 index 0000000..b30b66f --- /dev/null +++ b/convert_and_copy_exif.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -euo pipefail + +# 使用:convert_and_copy_exif.sh /path/to/source_dir [target_dir] +# SOURCE_DIR 必填:包含原始带 EXIF 的原图的文件夹 +# TARGET_DIR 可选:要处理的文件夹(默认当前目录) + +if [[ "${1:-}" == "" ]]; then + echo "Usage: $0 /path/to/source_dir [target_dir]" >&2 + exit 2 +fi + +SOURCE_DIR="$1" +TARGET_DIR="${2:-.}" + +# 依赖检查 +if ! command -v exiftool >/dev/null 2>&1; then + echo "exiftool not found. Please install exiftool." >&2 + exit 3 +fi + +# prefer magick if available (ImageMagick v7), otherwise use convert +if command -v magick >/dev/null 2>&1; then + IM_CONVERT="magick" +elif command -v convert >/dev/null 2>&1; then + IM_CONVERT="convert" +else + echo "ImageMagick (magick or convert) not found. Please install it." >&2 + exit 4 +fi + +# 处理扩展名列表(大小写无关) +shopt -s nullglob +mapfile -t files < <(find "$TARGET_DIR" -maxdepth 1 -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.webp" -o -iname "*.heic" -o -iname "*.tif" -o -iname "*.tiff" -o -iname "*.bmp" -o -iname "*.gif" \) -print0 | xargs -0 -I{} printf '%s\n' "{}") + +if [[ ${#files[@]} -eq 0 ]]; then + echo "No image files found in target directory: $TARGET_DIR" + exit 0 +fi + +for srcpath in "${files[@]}"; do + # 生成目标 jpg 文件路径(放在同一目录,保留原文件不覆盖) + dir=$(dirname -- "$srcpath") + base=$(basename -- "$srcpath") + name_noext="${base%.*}" + target_jpg="$dir/${name_noext}.jpg" + + # 如果源本身就是 .jpg/.jpeg,则将 target_jpg 指向原文件(不重复转码) + ext="${base##*.}" + lower_ext="${ext,,}" + if [[ "$lower_ext" == "jpg" || "$lower_ext" == "jpeg" ]]; then + target_jpg="$srcpath" + echo "Skipping convert (already jpg): $srcpath" + else + # 转码为 jpg(如果目标存在则跳过转码) + if [[ -f "$target_jpg" ]]; then + echo "Target JPG already exists, skipping convert: $target_jpg" + else + echo "Converting: $srcpath -> $target_jpg" + # -strip 在这里不使用,因为后面要用 exiftool 覆盖;保留像素信息 + "$IM_CONVERT" "$srcpath" -quality 95 "$target_jpg" + if [[ $? -ne 0 ]]; then + echo "Convert failed for $srcpath" >&2 + continue + fi + fi + fi + + # 在 SOURCE_DIR 中查找同名原图(任意扩展名),优先返回第一个匹配 + found_src="" + while IFS= read -r -d $'\0' cand; do + found_src="$cand" + break + done < <(find "$SOURCE_DIR" -type f -iname "${name_noext}.*" -print0) + + if [[ -z "$found_src" ]]; then + echo "No matching source with same name in $SOURCE_DIR for: $name_noext" >&2 + continue + fi + + # 使用 exiftool 按提供的命令模板:先清掉再从 found_src 拷贝所有标签,设置 Artist 和 清空 UserComment,Orientation Normal + echo "Copying EXIF from $found_src -> $target_jpg" + exiftool -overwrite_original -all= -tagsFromFile "$found_src" "-all:all>all:all" -Artist="Paul" -UserComment= -Orientation=Normal "$target_jpg" >/dev/null 2>&1 + if [[ $? -eq 0 ]]; then + echo "EXIF copied: $target_jpg" + else + echo "Failed to copy EXIF for $target_jpg" >&2 + fi +done + +echo "Done." diff --git a/iphone-photo-format.sh b/iphone-photo-format.sh deleted file mode 100755 index e4acad5..0000000 --- a/iphone-photo-format.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -# 将 iPhone 拍摄的照片转换格式为 jpg 并处理 exif 信息 - -# 创建文件夹 output -mkdir -p output - -# 遍历当前文件夹下的所有 heic 和 png 文件 -for file in *.{HEIC,heic,PNG,png,JPG,jpg}; do - - # 跳过不存在的文件 - if [[ ! -f "$file" ]]; then - continue - fi - - # 跳过自己改的图片 - if [[ $filename == *"MODIFIED"* ]] || [[ $filename == *"MERGED"* ]]; then - echo "文件名包含 MODIFIED 或 MERGED" - continue - fi - - # 获取图片名并创建新的文件名 - filename=$(basename "$file") - extension="${filename##*.}" - new_extension="jpg" - new_filename="${filename%.*}.$new_extension" - - # 检查输出文件是否已存在 - if [[ -e "output/$new_filename" ]]; then - echo "Skipping existing file: output/$new_filename" - continue - fi - - if [[ "${filename##*.}" == "png" || "${filename##*.}" == "PNG" ]]; then - # 如果是 PNG 图片,直接转换为 WebP 格式,大概率是个截图 - new_filename="${filename%.*}.webp" - - # 使用 ImageMagick 直接处理 PNG 图片 - magick "$file" -gravity center -quality 80 output/$new_filename - else - # 判断图片是竖屏的还是横屏的 - # 使用 identify 命令判断图片的宽度和高度 - width=$(identify -format "%w" "$file") - height=$(identify -format "%h" "$file") - - # 指定图片大小 - if [ $width -ge $height ]; then - new_size="2000x1500" - else - new_size="1500x2000" - fi - - # 使用 ImageMagick 处理图片 - magick "$file" -gravity center -resize "$new_size^" -extent "$new_size" -quality 80 output/$new_filename - fi - - # 使用 exiftool 抹掉图片的 gps 信息,并设置作者名称为 Paul - exiftool -overwrite_original -gps:all= -artist="奇趣保罗" -CreatorTool= "output/$new_filename" - - echo "\n\n" - -done diff --git a/iphone-sony-photo-format.sh b/iphone-sony-photo-format.sh deleted file mode 100755 index fd9741e..0000000 --- a/iphone-sony-photo-format.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# 这个脚本用于将图片生成成适合上传到小窝的分辨率,降低整体大小 -# 这里默认所有的照片都是从索尼相机过来的并且比例是 2:3 - -# 创建文件夹 output -mkdir -p output - -# 遍历当前文件夹下的所有 heic 和 png 文件 -for file in *.{HEIC,heic,HEIF,heif,PNG,png,JPG,jpg}; do - - # 跳过不存在的文件 - if [[ ! -f "$file" ]]; then - continue - fi - - # 跳过自己改的图片 - if [[ $filename == *"MODIFIED"* ]] || [[ $filename == *"MERGED"* ]]; then - echo "文件名包含 MODIFIED 或 MERGED" - continue - fi - - # 获取图片名并创建新的文件名 - filename=$(basename "$file") - extension="${filename##*.}" - new_extension="jpg" - new_filename="${filename%.*}.$new_extension" - - # 检查输出文件是否已存在 - if [[ -e "output/$new_filename" ]]; then - echo "Skipping existing file: output/$new_filename" - continue - fi - -# if [[ "${filename##*.}" == "png" || "${filename##*.}" == "PNG" ]]; then - # 使用 ImageMagick 直接处理 PNG 图片 -# magick "$file" -gravity center -quality 80 output/$new_filename -# else - # 判断图片是竖屏的还是横屏的 - # 使用 identify 命令判断图片的宽度和高度 - width=$(identify -format "%w" "$file") - height=$(identify -format "%h" "$file") - - # 指定图片大小 - if [ $width -ge $height ]; then - new_size="2250x1500" - else - new_size="1500x2250" - fi - - # 使用 ImageMagick 处理图片 - magick "$file" -gravity center -resize "$new_size^" -extent "$new_size" -quality 80 "output/$new_filename" -# fi - - # 使用 exiftool 抹掉图片的 gps 信息,并设置作者名称为 Paul - exiftool -overwrite_original -gps:all= -artist="奇趣保罗" -CreatorTool= "output/$new_filename" - - echo '\n\n' - -done diff --git a/photo-toolkit/format.js b/photo-toolkit/format.js index 133d5c9..a1a82b7 100644 --- a/photo-toolkit/format.js +++ b/photo-toolkit/format.js @@ -41,7 +41,7 @@ function processImage(inputPath, outputPath, predetect) { try { if (type === IMAGE_TYPES.SCREENSHOT) { execSync( - `magick "${inputPath}" -gravity center -quality 80 "${finalOutputPath}"`, + `magick "${inputPath}" -auto-orient -gravity center -quality 80 "${finalOutputPath}"`, { stdio: 'inherit' } ); } else { @@ -51,7 +51,7 @@ function processImage(inputPath, outputPath, predetect) { ? `-gravity center -resize "${target.size}^" -extent "${target.size}"` : `-resize "${target.size}"`; execSync( - `magick "${inputPath}" ${resizeArgs} -quality 80 "${finalOutputPath}"`, + `magick "${inputPath}" -auto-orient ${resizeArgs} -quality 80 "${finalOutputPath}"`, { stdio: 'inherit' } ); } diff --git a/photo-toolkit/recover-exif.js b/photo-toolkit/recover-exif.js index bc58bf3..db95e76 100644 --- a/photo-toolkit/recover-exif.js +++ b/photo-toolkit/recover-exif.js @@ -63,9 +63,10 @@ function recoverExif(targetFile, sourceFile, succeedDir) { } try { - // 使用 exiftool 复制 EXIF 信息 + // 从原图拷 EXIF。后期软件(如美图)往往已把旋转烧进像素, + // 若原样带回 Orientation,看图软件会再转一次;强制 Normal 避免这个坑。 execSync( - `exiftool -overwrite_original -all= -UserComment= -tagsFromFile "${sourceFile}" "${targetFile}"`, + `exiftool -overwrite_original -all= -UserComment= -tagsFromFile "${sourceFile}" -Orientation=Normal "${targetFile}"`, { stdio: 'inherit' } ); diff --git a/photo-toolkit/utils.js b/photo-toolkit/utils.js index 81ea778..9071ba8 100644 --- a/photo-toolkit/utils.js +++ b/photo-toolkit/utils.js @@ -34,8 +34,11 @@ function question(rl, prompt) { // 获取图片尺寸 function getImageDimensions(filePath) { try { - const width = execSync(`identify -format "%w" "${filePath}"`, { encoding: 'utf-8' }).trim(); - const height = execSync(`identify -format "%h" "${filePath}"`, { encoding: 'utf-8' }).trim(); + // -auto-orient:按 EXIF Orientation 换算视觉宽高,避免竖拍图被当成横图 + const output = execSync(`identify -auto-orient -format "%w %h" "${filePath}"`, { + encoding: 'utf-8', + }).trim(); + const [width, height] = output.split(/\s+/); return { width: parseInt(width), height: parseInt(height) }; } catch (error) { console.error(`获取图片尺寸失败: ${filePath}`); diff --git a/recover-modified-photo-exif.sh b/recover-modified-photo-exif.sh deleted file mode 100755 index 3ffc3e5..0000000 --- a/recover-modified-photo-exif.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash - -# 这个脚本用于还原 EXIF 数据,传递原始 EXIF 图片的路径(第一个参数),还原修改过 EXIF 的图片的路径(第二个参数) -# Example: ./recover-modified-photo-exif.sh /Volumes/未命名导出 . - -# 检查参数 -if [ "$#" -ne 2 ]; then - echo "用法: $0 <源文件夹路径> <被修改的文件夹路径>" - exit 1 -fi - -SOURCE_DIR="$1" -TARGET_DIR="$2" -SUCCEED_DIR="$TARGET_DIR/succeed" - -# 检查并创建 succeed 目录 -if [ ! -d "$SUCCEED_DIR" ]; then - mkdir -p "$SUCCEED_DIR" - echo "创建 succeed 目录: $SUCCEED_DIR" -fi - -# 处理被修改的文件夹中的所有 PNG 文件 -for png_file in "$TARGET_DIR"/*.png; do - # 跳过 succeed 目录中的文件 - if [[ "$png_file" == *"/succeed/"* ]]; then - continue - fi - - # 检查文件是否存在(防止没有 png 文件时报错) - if [ ! -f "$png_file" ]; then - continue - fi - - # 获取文件名(不包括路径和扩展名) - filename=$(basename "$png_file") - base_filename="${filename%.png}" - jpg_file="$TARGET_DIR/$base_filename.jpg" - succeed_jpg_file="$SUCCEED_DIR/$base_filename.jpg" - - # 如果当前目录或 succeed 目录下同名 JPG 文件已存在,则跳过 - if [ -f "$jpg_file" ] || [ -f "$succeed_jpg_file" ]; then - echo "$jpg_file 或 $succeed_jpg_file 已存在,跳过 PNG 转换" - continue - fi - - # 使用 ImageMagick 的 convert 命令将 PNG 转换为 JPG,设置质量为100(无压缩) - convert "$png_file" -quality 100 "$jpg_file" - echo "$filename 已转换为 JPG: $jpg_file" -done - -# 遍历被修改的文件夹中的所有 JPG 文件 -for target_file in "$TARGET_DIR"/*.jpg; do - # 跳过 succeed 目录中的文件 - if [[ "$target_file" == *"/succeed/"* ]]; then - continue - fi - - # 获取文件名(不包括路径) - filename=$(basename "$target_file") - - # 去掉 .jpg 后缀以便查找源文件 - base_filename="${filename%.jpg}" - - # 检查源文件夹中是否存在同名文件 - if [ -f "$SOURCE_DIR/$filename" ]; then - # 使用 exiftool 复制 EXIF 信息 - exiftool -overwrite_original -all= -UserComment= -tagsFromFile "$SOURCE_DIR/$filename" "$target_file" - mv "$target_file" "$SUCCEED_DIR/" - echo "jpg 匹配成功,已移动到 succeed 文件夹" - # 检查源文件夹中是否存在同名的 HEIF 文件 - elif [ -f "$SOURCE_DIR/$base_filename.heic" ]; then - # 使用 exiftool 复制 EXIF 信息 - exiftool -overwrite_original -tagsFromFile "$SOURCE_DIR/$base_filename.heic" "$target_file" - mv "$target_file" "$SUCCEED_DIR/" - echo "heic 匹配成功,已移动到 succeed 文件夹" - elif [ -f "$SOURCE_DIR/$base_filename.heif" ]; then - # 使用 exiftool 复制 EXIF 信息 - exiftool -overwrite_original -tagsFromFile "$SOURCE_DIR/$base_filename.heif" "$target_file" - mv "$target_file" "$SUCCEED_DIR/" - echo "heif 匹配成功,已移动到 succeed 文件夹" - elif [ -f "$SOURCE_DIR/$base_filename.HIF" ]; then - # 使用 exiftool 复制 EXIF 信息 - exiftool -overwrite_original -tagsFromFile "$SOURCE_DIR/$base_filename.HIF" "$target_file" - mv "$target_file" "$SUCCEED_DIR/" - echo "HIF 匹配成功,已移动到 succeed 文件夹" - else - echo "$filename 未找到,保留在原位置" - fi -done - -# 处理被修改的文件夹中的所有大写 JPG 文件 -for target_file in "$TARGET_DIR"/*.JPG; do - # 跳过 succeed 目录中的文件 - if [[ "$target_file" == *"/succeed/"* ]]; then - continue - fi - - # 获取文件名(不包括路径) - filename=$(basename "$target_file") - - # 执行 exiftool 命令去除 GPS 信息并设置作者,删除美图秀秀生成的备注信息 - exiftool -overwrite_original -UserComment= -gps:all= -artist="奇趣保罗" -CreatorTool= "$target_file" -done - -echo "EXIF 信息更新完成!" -