Compress a directory of screenshots

To preserve the original creation date and other metadata of the files during the compression process, we can use the touch command to reset the timestamps after the compression.

Here is the modified script that keeps the original metadata:

#!/bin/bash

# Function to remove leading and trailing single quotes
strip_quotes() {
    echo "$1" | sed "s/^'\(.*\)'$/\1/"
}

# Function to compress a single file and preserve metadata
compress_file() {
    local file="$1"
    local dir=$(dirname "$file")
    local original_filename=$(basename "$file")
    local original_extension="${original_filename##*.}"
    local original_name="${original_filename%.*}"

    # Save original file metadata
    local original_metadata=$(stat --format "%y" "$file")

    # Rename the original file with _original appended before the extension
    local original_file="${dir}/${original_name}_original.${original_extension}"
    mv "$file" "$original_file"

    # Compress using pngquant and save with the original filename
    pngquant --force --ext .png - < "$original_file" > "$file"

    # Restore original metadata
    touch -d "$original_metadata" "$file"
}

# Function to compress all PNG files in a directory and preserve metadata
compress_directory() {
    local directory="$1"

    # Rename the directory with _original appended
    mv "$directory" "${directory}_original"

    # Create a new directory with the original name
    mkdir "$directory"

    # Loop through all PNG files in the _original directory
    for file in "${directory}_original"/*.png; do
        if [[ -f "$file" ]]; then
            filename=$(basename "$file")
            echo "Compressing $filename..."

            # Save original file metadata
            local original_metadata=$(stat --format "%y" "$file")

            # Compress using pngquant and save to the new directory
            pngquant --force --ext .png - < "$file" > "$directory/$filename"

            # Restore original metadata
            touch -d "$original_metadata" "$directory/$filename"
        fi
    done
}

# Main script starts here
if [[ $# -eq 0 ]]; then
    echo "Usage: $0 <file_or_directory>"
    exit 1
fi

# Handle single input argument
input="$1"
input=$(strip_quotes "$input")

# Check if input is a file
if [[ -f "$input" ]]; then
    compress_file "$input"
    echo "File compression complete. Original renamed to ${input%.*}_original.${input##*.}"
    exit 0
fi

# Check if input is a directory
if [[ -d "$input" ]]; then
    compress_directory "$input"
    echo "Directory compression complete. Original renamed to ${input}_original."
    exit 0
fi

# If neither file nor directory
echo "Error: '$input' is not a valid file or directory."
exit 1

Explanation:

  1. strip_quotes() function: This function is used to remove any leading and trailing single quotes from a given path.

  2. compress_file() function:

    • Extracts the directory (dir), original filename (original_filename), extension (original_extension), and base name without the extension (original_name).
    • Saves the original file metadata (creation date) using the stat command.
    • Constructs the new name for the original file by appending _original before the file extension.
    • Moves the original file to the new name.
    • Uses pngquant to compress the renamed original file and save it with the original filename.
    • Restores the original metadata using the touch command.
  3. compress_directory() function:

    • Renames the directory by appending _original.
    • Creates a new directory with the original name.
    • Iterates over all PNG files in the renamed original directory.
    • Saves the original file metadata (creation date) using the stat command.
    • Compresses each PNG file using pngquant and saves them to the new directory.
    • Restores the original metadata using the touch command.
  4. Main Script:

    • Checks if there is exactly one argument provided. If not, it displays usage information.
    • Determines whether the input is a file or a directory and calls the appropriate function.
    • Outputs an error message if the input is neither a file nor a directory.

Usage:

  1. Save the Script: Copy the script into a file, e.g., compress_and_rename.sh.

  2. Make It Executable:

    chmod +x compress_and_rename.sh
    
  3. Run the Script:

    ./compress_and_rename.sh <file_or_directory>
    

Replace <file_or_directory> with the path to the file or directory you want to compress. The script will now correctly handle the renaming of the original file or directory with _original appended before the extension, compress the PNG files using pngquant, and preserve the original metadata.