4.2 KiB
iOS
iPhoto Export
-
Download all your photos in batches of 1000
-
Extract all zip files
-
Use
findto copy all files to photo-archivefind ./icloud -type f -not -name '*.zip' -print0 | xargs -0 -I % /bin/bash -c 'cp -v --backup=numbered "%" photo-archive/'
-
Verify all photos were copied successfully
find ./icloud -type f -not -name '*.zip' | wc -l find ./photo-archive -type f | wc -l
-
Rename duplicates so they have the correct extension
# Collect duplicates find photo-archive -name '*.~*' > duplicates.txt cat duplicates.txt | wc -l # dry run convert duplicates named *.~n~ to something else for item in $(cat duplicates.txt); do echo mv $item photo-archive/$(python -c "from pathlib import Path; number=Path(\"$item\").suffix ;name = Path(Path(\"$item\").stem); print(name.stem + '_' + number.replace('~','').replace('.','') + name.suffix)"); done # actual rename for item in $(cat duplicates.txt); do mv $item photo-archive/$(python -c "from pathlib import Path; number=Path(\"$item\").suffix ;name = Path(Path(\"$item\").stem); print(name.stem + '_' + number.replace('~','').replace('.','') + name.suffix)"); done # verify find photo-archive -name '*.~*' find ./photo-archive -type f | wc -l -
Remove live photos
Live photos show up as a .MOV files. They should be the only .MOV files in the folder. Remove them with:
find photo-archive -name '*.MOV' -delete # verify find ./photo-archive -type f | wc -l -
Organize by year
To keep your photos folder from getting too bloated you should organize your photos into subfolders by (at least) year.
Phockup seems to be able to do this:
podman run -v ~/Pictures:/mnt ivandokov/phockup:latest /mnt/iphone /mnt/iOS -d YYYY
Photos Export
https://github.com/icloud-photos-downloader/icloud_photos_downloader
podman run -it --rm --name icloudpd \
-v $(pwd)/iPhotos:/data \
-e TZ=America/New_York \
icloudpd/icloudpd:latest \
icloudpd \
--directory /data \
--username apple@ducoterra.net \
--watch-with-interval 3600
You can browse all downloaded photos with feh:
pacman -S feh
feh --recursive --scale-down -d -S filename $(pwd)/iPhotos
Extensions
- PNG
- HEIC: iOS HDR photo
- MOV
- DNG: iOS raw photo
- JPG
- 3gp: quicktime video file
- MP4
- GIF
- WEBP: Google photo container
- CR2: Canon raw photo
Conversion
You will need imagemagick and libraw:
pacman -S imagemagick libraw
Then you can convert any image with magick:
magick input.HEIC output.png
magick input.HEIC output.jpeg
You get a list of all unique file extensions with:
find . -type f | awk -F. '!a[$NF]++{print $NF}'
Then use those file extensions to create a find command:
# -o means "or" in this case
# Parentheses are required
find . -type f -printf '%p\n' \( \
-iname '*.jpg' \
-o -iname '*.heic' \
-o -iname '*.dng' \
-o -iname '*.png' \
-o -iname '*.WEBP' \
-o -iname '*.cr2' \
\)
And then use xargs with magick to convert the images:
find . -type f \( \
-iname '*.jpg' \
-o -iname '*.heic' \
-o -iname '*.dng' \
-o -iname '*.png' \
-o -iname '*.WEBP' \
-o -iname '*.cr2' \
\) -print0 | xargs -0 -P $(nproc) -I % python -c "\
import subprocess; \
from pathlib import Path; \
to_folder = '/run/media/ducoterra/photos/'; \
p = Path(\"%\"); \
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.jpg'; \
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
subprocess.run(['magick', \"%\", to_folder + realpath])"
And then videos:
find . -type f \( \
-iname '*.MOV' \
-o -iname '*.3gp' \
-o -iname '*.MP4' \
-o -iname '*.GIF' \
\) -print0 | xargs -0 -I % python -c "\
import subprocess; \
from pathlib import Path; \
to_folder = '/run/media/ducoterra/photos/'; \
p = Path(\"%\"); \
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.mp4'; \
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
subprocess.run(['ffmpeg', '-i', '%', '-c', 'copy', to_folder + realpath])"