Quando pubblico fotografie sul blog cerco sempre di fare due cose:

  1. ridurre il peso dei file
  2. rimuovere i metadati

Le fotografie scattate con smartphone o fotocamere moderne possono facilmente pesare 5–10 MB, ma una pagina web non ha bisogno di immagini così grandi per essere visualizzata correttamente.

Inoltre i file immagine contengono spesso molte informazioni nascoste che non è necessariamente una buona idea pubblicare online.

Per questo motivo uso un piccolo script Bash che:

  • ridimensiona le immagini
  • riduce la qualità
  • converte tutto in webp
  • rimuove i metadati
  • mostra quanto spazio viene risparmiato

Perché rimuovere i metadati

Le immagini contengono spesso dati EXIF e altri metadati. Alcuni esempi comuni sono:

  • coordinate GPS
  • modello della fotocamera
  • numero di serie della fotocamera
  • data e ora precise dello scatto
  • software usato per modificare la foto
  • orientamento e impostazioni di scatto

Il problema più evidente riguarda le coordinate GPS: se abilitate sul telefono, possono indicare esattamente dove è stata scattata la fotografia.

Pubblicare immagini senza rimuovere questi dati può quindi rivelare:

  • dove si trova casa propria
  • dove si scattano abitualmente le foto
  • informazioni sulla propria attrezzatura

Per questo motivo lo script utilizza l’opzione -strip di ImageMagick, che rimuove tutti i metadati incorporati nel file.

Cosa fa lo script

Lo script:

  • prende una directory come input
  • crea una cartella resize
  • ridimensiona le immagini a massimo 1600×1600
  • converte tutto in WebP
  • riduce la qualità a 75
  • elimina i metadati
  • stampa una tabella con la riduzione di dimensione

Lo script

set -euo pipefail

if [[ $# -ne 1 ]]; then
  echo "Uso: $0 /percorso/cartella"
  exit 1
fi

INPUT_DIR="$1"
OUTPUT_DIR="$INPUT_DIR/resize"

MAX_SIZE="1600x1600>"
QUALITY="75"

if [[ ! -d "$INPUT_DIR" ]]; then
  echo "Errore: la cartella '$INPUT_DIR' non esiste."
  exit 1
fi

mkdir -p "$OUTPUT_DIR"

shopt -s nullglob nocaseglob

count=0
total_original=0
total_new=0

for file in "$INPUT_DIR"/*; do

  # salta eventuali directory (in particolare resize)
  [[ -d "$file" ]] && continue

  case "$file" in
    *.jpg|*.jpeg|*.png|*.heic|*.heif)
      ;;
    *)
      continue
      ;;
  esac

  filename="$(basename "$file")"
  name="${filename%.*}"
  output_file="$OUTPUT_DIR/${name}.webp"

  orig_size=$(stat -c%s "$file")

  magick "$file" \
    -auto-orient \
    -resize "$MAX_SIZE" \
    -strip \
    -quality "$QUALITY" \
    "$output_file"

  new_size=$(stat -c%s "$output_file")

  reduction=$(awk "BEGIN {printf \"%.1f\", (1 - $new_size / $orig_size) * 100}")

  printf "%-25s  %7.1f KB → %7.1f KB   (%5s%%)\n" \
    "$filename" \
    "$(awk "BEGIN {print $orig_size/1024}")" \
    "$(awk "BEGIN {print $new_size/1024}")" \
    "$reduction"

  total_original=$((total_original + orig_size))
  total_new=$((total_new + new_size))
  count=$((count + 1))

done

if [[ "$count" -eq 0 ]]; then
  echo "Nessuna immagine trovata."
  exit 0
fi

echo
echo "-------------------------------------------"

total_reduction=$(awk "BEGIN {printf \"%.1f\", (1 - $total_new / $total_original) * 100}")

printf "Immagini processate: %d\n" "$count"
printf "Totale originale:    %.2f MB\n" "$(awk "BEGIN {print $total_original/1024/1024}")"
printf "Totale finale:       %.2f MB\n" "$(awk "BEGIN {print $total_new/1024/1024}")"
printf "Riduzione totale:    %s %%\n" "$total_reduction"

echo
echo "Output salvato in:"
echo "$OUTPUT_DIR"

Come lo uso

Lo script si usa semplicemente passando una cartella contenente immagini:

./script.sh foto

Alla fine tutte le immagini processate si trovano in:

foto/resize

e lo script stampa anche una piccola statistica sulla riduzione complessiva.

Nella maggior parte dei casi le immagini passano da diversi megabyte a qualche centinaio di kilobyte, più che sufficienti per essere visualizzate su una pagina web.