RhetTbull / osxphotos

Python app to work with pictures and associated metadata from Apple Photos on macOS. Also includes a package to provide programmatic access to the Photos library, pictures, and metadata.
MIT License
1.73k stars 92 forks source link

Ability to resize on convert-to-jpeg #1536

Open odedia opened 2 weeks ago

odedia commented 2 weeks ago

I use osxphotos to create a mobile-friendly version of my library, currently targetted for Immich. I don't really need the full quality and size of the images for that mobile library.

It would be nice to have an option for --jpeg-resize-by or something of that nature, that would define the percentage by which to shrink the image. Something like --jpeg-resize-by 0.7 would create an image that is 70% the size of the original. It would also be a good idea to define a minimum resize threshold so that osxphotos would not resize images less than a certain size. Something like --jpeg-resize-minimum 300px would indicate that if the short edge of the image is already 300 pixels or less, it would not be resized.

As a side note - it would also be very helpful to have a similar properties for videos (something like --video-max-size 720p), although I can see why that could be more difficult to implement.

RhetTbull commented 1 week ago

These would be challenging to implement while ensuring metadata is preserved, etc. Video in particular would be challenging. I view osxphotos export primarily as an archival / backup tool and this seems like an edge case. Perhaps a better solution would be to use the --post-function or --post-command to run a function/command on the exported photo to do the conversion after it's been exported by OSXPhotos. One issue with this is that the export command does not update the signature of the exported file(s) in the database so subsequent exports with --update will overwrite/re-export the images. I've thought about fixing this but it would take some work. One alternative might be to implement a --export-function or --pre-function option that would stage the file to be exported in a temp directory and pass it to your custom function/script for processing and maybe to do the actual export. This would let you use the osxphotos export logic to do anything you want with the photos even if it wasn't a simple export. The signature of the processed file would then be updated in the export database. I think this is more flexible approach than adding specific commands for resizing, etc.

RhetTbull commented 1 week ago

If you use --ignore-signature with a --post-command or --post-function, then the update should work OK. OSXPhotos would not be able to detect if a file in the export directory changed and thus had to be re-exported but would detect changes in Photos and update exported files accordingly. You could write a bash script or python function to do the resizing using ffmpeg, image magik, etc. to replace the original exported by osxphotos.

See example here.

--post-command CATEGORY COMMAND
                                Run COMMAND on exported files of category CATEGORY.  CATEGORY can be one of:
                                exported, new, updated, skipped, missing, exif_updated, touched,
                                converted_to_jpeg, sidecar_json_written, sidecar_json_skipped,
                                sidecar_exiftool_written, sidecar_exiftool_skipped, sidecar_xmp_written,
                                sidecar_xmp_skipped, error. COMMAND is an osxphotos template string, for
                                example: '--post-command exported "echo {filepath|shell_quote} >>
                                {export_dir}/exported.txt"', which appends the full path of all exported
                                files to the file 'exported.txt'. You can run more than one command by
                                repeating the '--post-command' option with different arguments. See also
                                --post-command-error and --post-function.See Post Command below.
--post-command-error ACTION     Specify either `continue` or `break` for ACTION to control behavior when a
                                post-command fails. If `continue`, osxphotos will log the error and continue
                                processing. If `break`, osxphotos will stop processing any additional
                                --post-command commands for the current photo but will continue with the
                                export. Without --post-command-error, osxphotos will abort the export if a
                                post-command encounters an error.
--post-function filename.py::function
                                Run function on exported files. Use this in format: --post-function
                                filename.py::function where filename.py is a python file you've created and
                                function is the name of the function in the python file you want to call.
                                The function will be passed information about the photo that's been exported
                                and a list of all exported files associated with the photo. You can run more
                                than one function by repeating the '--post-function' option with different
                                arguments. You may also specify a post function using a URL in format
                                --post-function 'https://path/to/module.py::function' See Post Function
                                below.
oPromessa commented 1 week ago

Would the --preview option mentioned in #566 do the trick?

I did try it at the time but don't recall what it does with videos.

odedia commented 1 week ago

Not sure. I'm seeing a small version and a large version of the same RAW+JPEG source in the output folder:

image

I used the following command:

osxphotos export --export-by-date --from-date 2024-04-25 --skip-raw --update --preview --exiftool --preview-suffix "" --touch-file preview

Also the videos seem to be the original size and quality.

RhetTbull commented 1 week ago

The only preview available for videos is a jpeg of the thumbnail frame.