-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
During export, Ignore edits that are only rotations? #1591
Comments
This might be possible by examine the adjustments data decoded by osxphotos. Rotated image, no edits: No adjustments and orientation is set. {
"editor": "com.apple.Photos",
"format_id": "com.apple.photo",
"base_version": 0,
"format_version": "1.4",
"adjustments": [],
"metadata": {
"masterHeight": 3024,
"masterWidth": 3024,
"orientation": 8
},
"orientation": 8,
"adjustment_format_version": 1,
"version_info": {
"buildNumber": "22G90",
"appVersion": "560.0.110",
"schemaRevision": 0,
"platform": "macOS"
},
"timestamp": "2024-06-21T05:30:21+00:00"
} Edited image: "adjustments" contains data (but also orientation is set even though image not rotated) {
"editor": "com.apple.Photos",
"format_id": "com.apple.photo",
"base_version": 0,
"format_version": "1.4",
"adjustments": [
{
"formatVersion": 1,
"enabled": 1,
"settings": {
"offsetTone": 0,
"offsetGrain": 0,
"offsetStrength": 0,
"offsetNeutralGamma": 0,
"auto": 0,
"inputBlackAndWhite": 0.04888947315705128
},
"identifier": "SmartBlackAndWhite",
"formatIdentifier": "com.apple.photo"
}
],
"metadata": {
"masterHeight": 3024,
"masterWidth": 3024,
"orientation": 1
},
"orientation": 1,
"adjustment_format_version": 1,
"version_info": {
"buildNumber": "22G90",
"appVersion": "560.0.110",
"schemaRevision": 0,
"platform": "macOS"
},
"timestamp": "2024-06-21T05:34:03+00:00"
} Edited and rotated image "adjustments" contains data and orientation is also set. {
"editor": "com.apple.Photos",
"format_id": "com.apple.photo",
"base_version": 0,
"format_version": "1.4",
"adjustments": [
{
"formatVersion": 1,
"enabled": 1,
"settings": {
"offsetTone": 0,
"offsetGrain": 0,
"offsetStrength": 0,
"offsetNeutralGamma": 0,
"auto": 0,
"inputBlackAndWhite": 0.23603640825320515
},
"identifier": "SmartBlackAndWhite",
"formatIdentifier": "com.apple.photo"
}
],
"metadata": {
"masterHeight": 3024,
"masterWidth": 3024,
"orientation": 3
},
"orientation": 3,
"adjustment_format_version": 1,
"version_info": {
"buildNumber": "22G90",
"appVersion": "560.0.110",
"schemaRevision": 0,
"platform": "macOS"
},
"timestamp": "2024-06-21T05:38:02+00:00"
} It appears that if the photo shows as edited and "adjustments" is null, then the photo has been rotated but not edited. This could be used to filter the images that were only rotated. |
I wonder if a more general purpose option would be better? For example, To skip rotated images then, you'd do:
This would skip any edited version if there was an adjustments file but the adjustments data was missing. The It's not as intuitive perhaps as |
Wow--I love that idea. Way more extensible than what I proposed |
I'm just learning |
@felciano If you save the following as "adjustments.py" then select some photos in Photos and run the command with """Print out JSON for adjustments info for selected photos
Run with: osxphotos run adjustments.py
"""
from __future__ import annotations
import json
import osxphotos
from osxphotos.cli import selection_command
@selection_command
def adjustments(photos: list[osxphotos.PhotoInfo], **kwargs):
"""Prints out the adjustments info, if any, for each selected photo as JSON."""
json_data = []
for photo in photos:
data = {
"uuid": photo.uuid,
"filename": photo.original_filename,
"hasadjustments": photo.hasadjustments,
}
if photo.adjustments:
data |= photo.adjustments.asdict()
data.pop("data") # remove the raw data field
json_data.append(data)
print(json.dumps(json_data, indent=4))
if __name__ == "__main__":
adjustments() |
We could do the same for originals: |
Would this example help? export.py Alternatively, @RhetTbull I recall you've made available in the API all the export options/functionality so that one could take the benefit of all the options plus some added control via API. Don't seem to find that reference. |
@oPromessa I don't think it's in the docs (on mobile so not easy to check) but export_cli() in osxphotos/cli/export.py can be called with any export options you want to have programmatic access to the export command. osxphotos/osxphotos/cli/export.py Line 1119 in 5191041
This won't solve the problem though because it lacks logic to skip only certain edits. I think this can be implemented fairly easily though and once done, you'll be able to use any criteria you want for determining which assets are exported. |
I looked at the code needed to implement this. I think this will be fairly straightforward to implement. The |
I confirmed this dumps info about the currently selected items, and any untouched photo lacks the Is there an obvious way to implement logic along the lines of "ignore rotated photos if the unrotated version has already been exported"? This would support the original use case (above) but also work for cases where you make a copy to correct a photo rotation and then delete the original (although that is rare in my case) |
@all-contributors please add @felciano for research, ideas |
I don't think this would be easy outside the original use case (once I implement the |
We had trouble processing your request. Please try again later. |
@RhetTbull regarding the "ignore rotated photos if the unrotated version has already been exported" explanation: thanks for clarifying; makes sense that would be hard to implement in Let me provide a broader use case for this feature request:
Is there perhaps a different way to think about using |
@felciano because edits (including rotations) in Photos are always non-destructive, the original image is preserved. This means you can check an exported original against originals in Photos. A rotation will only affect the edited version that is exported or the original if exported with For example,
Then I rotated the image in Photos and ran
OSXPhotos correctly detects that the exported original matches an asset already in the library. Now, if you applied the rotation by changing the EXIF orientation flag then the photos would not match -- the import check only verifies exact duplicates. To do so, it uses a fingerprint (file hash) function that is also used by Photos and conveniently stored in the Photos database. Thus OSXPhotos does not need to compute the hash for every photo in the library, it can simply query the database to see if there's a match. If you wanted to do this for an image with EXIF data that changed, you'd have to use some sort of "visual diff". Such algorithms exist but this would be much more computationally complex. Perhaps an idea for a future osxphotos feature? |
Use --skip-edit
What if you use --skip-edit option to actually have osxphotos only export originals. You can then compare them with your folder. You can also use the --export-as-hardlink to save space on exported files by linking directly to the actual original file (does not work with --exiftool). You may also use Gemini 2 to find duplicated images across your two folders.
Photos duplicates check on importAlternatively, when you select a folder to import in Photos it does try to find duplicates already imported; prprior to actually import them. I don't fully trust it 😉 but if they are actually the very same it may give you a pointer to duplicates. |
@RhetTbull thanks for the pointers. I've tried this workflow with Gemini 2, and can't figure out how to get it to reliably only elect to delete duplicates from one of the two folders. Despite indicating that it should never delete from under a particular root tree, when I tell it to "Select Any" file to delete, it will sometimes pick the duplicate that since under that "never touch" space. I've reproduced this and filed a report with the developers, but no reply. I've ended hacking my around it by doing full exports, and then using https://github.com/pkolaczk/fclones with some post-processing to find the duplicates to delete. |
Is your feature request related to a problem? Please describe.
I've started using
osxphotos
to export images from a handful of libraries. In many cases I end up with "duplicated" photos exported in the sense that aimage.jpg
is exported as well as animage_edited.jpg
alternative. In many cases, the only "edit" in the second one is that the photo was rotated, which is frustrating because it doubles the amount of exported files for essentially a trivial change.Describe the solution you'd like
I would love a
--ignore-rotations
flag that will not export edited photos if their only edit is a rotation.Describe alternatives you've considered
I've tried opening the exported photos in Preview and rotating to the same orientation, but unfortunately this results in different file sizes. So something about the rotate operation and/or the subsequent export is lossy, such that an subsequent rotation won't undo the change.
Additional context
I would be OK with a significant delay in the export process to support this operation. For example, if there is a native Photos way to un-rotate and then compare the images to confirm they are now identical, that might do the trick.
The text was updated successfully, but these errors were encountered: