#!/bin/bash # # zip_images_resize Resizing large JPGs in ZIPs # Based on: https://shkspr.mobi/blog/2016/12/converting-rar-to-zip-in-linux/ # # Usage: xxx.sh file [file ...] if [ $# -eq 0 ]; then echo "Usage: $0 file.zip [file2.zip ...]" exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/config.sh" echo "Resizing large JPGs in ZIPs" # Use RAM disk for temporary files. WORKDIR="/dev/shm/" # Cleanup function cleanup_temp() { if [ -n "$SAMPLE" ] && [ -f "$SAMPLE" ]; then rm -f "$SAMPLE" fi if [ -n "$TEMPDIR" ] && [ -d "$TEMPDIR" ]; then rm -r "$TEMPDIR" fi } # Count total files TOTAL_FILES=$# CURRENT_FILE=0 for INFILE in "$@"; do CURRENT_FILE=$((CURRENT_FILE + 1)) # Convert to absolute path INFILE="$(realpath "$INFILE")" echo "Processing file $CURRENT_FILE of $TOTAL_FILES: $INFILE" SAMPLE="" TEMPDIR="" trap cleanup_temp EXIT INT TERM # Check if already processed by sampling the first JPEG in the archive FIRST_JPEG=$(unzip -l "$INFILE" 2>/dev/null | grep -iE '\.(jpg|jpeg)$' | head -1 | awk '{print $NF}') if [ -n "$FIRST_JPEG" ]; then SAMPLE=$(mktemp -p "$WORKDIR" --suffix=.jpg) if unzip -p "$INFILE" "$FIRST_JPEG" > "$SAMPLE" 2>/dev/null; then COMMENT=$(~/Applications/magick identify -format "%c" "$SAMPLE" 2>/dev/null) rm -f "$SAMPLE" SAMPLE="" if [[ "$COMMENT" == "$MAGICK_COMMENT" ]]; then echo "Skipping $INFILE: already processed" trap - EXIT INT TERM continue fi else rm -f "$SAMPLE" SAMPLE="" fi fi OUTFILE="$(realpath "${INFILE%.zip}-compress.zip")" # Remove output file if it already exists if [ -e "${OUTFILE}" ]; then rm "${OUTFILE}" fi # Set name for the temp dir. This directory will be created under WORKDIR TEMPDIR=$(mktemp -p "$WORKDIR" -d) # Create a temporary folder for unzipped files echo "Extracting $INFILE" # extract files from zip if ! unzip "$INFILE" -d "$TEMPDIR"; then echo "Error: Failed to extract $INFILE" cleanup_temp continue fi # resize #convert '${TEMPDIR}/*.jpg' -set filename:fn '%[basename]' -resize 2800000@@\> -sampling-factor 4:2:0 -strip -quality 85% -colorspace RGB '%[filename:fn].jpg' if ! pushd "$TEMPDIR" > /dev/null; then echo "Error: Failed to change to temp directory" cleanup_temp continue fi "$SCRIPT_DIR/images_resize.sh" popd > /dev/null # Zip the files with no compression pushd "$TEMPDIR" > /dev/null if ! 7z a -tzip -mx=0 "$OUTFILE" ./*; then echo "Error: Failed to create ZIP" popd > /dev/null cleanup_temp continue fi popd > /dev/null # Alternative. MUCH SLOWER, but better compression # 7z a -mm=Deflate -mfb=258 -mpass=15 -r "$NEWNAME" * # Preserve file modification time touch -r "$INFILE" "$OUTFILE" # Check that OUTFILE exists and is not empty before deleting INFILE if [ ! -s "$OUTFILE" ]; then echo "Error: Output file is empty or does not exist. Keeping original file." cleanup_temp continue fi rm "$INFILE" mv "$OUTFILE" "$INFILE" # Delete the temporary directory cleanup_temp trap - EXIT INT TERM # OPTIONAL. Safe-remove the old file #gio trash "$OLDFILE" done echo "Conversion Done"