# iOS ## iPhoto Export 1. Download all your photos in batches of 1000 2. Extract all zip files 3. Use `find` to copy all files to photo-archive find ./icloud -type f -not -name '*.zip' -print0 | xargs -0 -I % /bin/bash -c 'cp -v --backup=numbered "%" photo-archive/' 4. Verify all photos were copied successfully find ./icloud -type f -not -name '*.zip' | wc -l find ./photo-archive -type f | wc -l 5. Rename duplicates so they have the correct extension ```bash # 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 ``` 6. Remove live photos Live photos show up as a .MOV files. They should be the only .MOV files in the folder. Remove them with: ```bash find photo-archive -name '*.MOV' -delete # verify find ./photo-archive -type f | wc -l ``` 7. Organize by year To keep your photos folder from getting too bloated you should organize your photos into subfolders by (at least) year. [Phockup](https://github.com/ivandokov/phockup) seems to be able to do this: ```bash podman run -v ~/Pictures:/mnt ivandokov/phockup:latest /mnt/iphone /mnt/iOS -d YYYY ``` ## Photos Export ```bash 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`: ```bash 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`: ```bash pacman -S imagemagick libraw ``` Then you can convert any image with magick: ```bash magick input.HEIC output.png magick input.HEIC output.jpeg ``` You get a list of all unique file extensions with: ```bash find . -type f | awk -F. '!a[$NF]++{print $NF}' ``` Then use those file extensions to create a find command: ```bash # -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: ```bash 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: ```bash 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])" ```