Developing software in the Real World

Migrating to Lightroom Classic from Apple Photos

I recently moved over to Adobe’s Lightroom Classic from Apple’s Photos in order to have more flexible non-destructive editing features – in particular local brushes. Rather confusingly, there’s also another Adobe product called Lightroom which is a new build for cloud-based storage which doesn’t (yet?) have all the features of Lightroom Classic. In particular, the lack of virtual copies and smart collection sets make Lightroom feel like a step backwards from Photos, while Lightroom Classic feels like a step forward in everything other than cloud storage and the Memories feature.

There are two main challenges for migrating from one photo management tool to another:

  • Transferring organisational folders and albums
  • Transferring photos edits

We need to do both for a successful migration.

Transferring folders and albums

The way that my photos are organised into folders and albums within Photos is stored in a database and as Lightroom Classic doesn’t have an “Import from Apple Photos” function, we’ll need to find a way to store which albums a photo is stored in within the photo itself and then recreate it in Lightroom Classic later. I chose to do this using keywords.

My organisational structure in Photos looks something like this:


Photos phpnw08 album

For each picture in an album, I chose to create a keyword that included the folders that that album was in using the “>” symbol as a separator. For example, the Published album in the screenshot above lives in the Conferences & Meetups -> 2008 -> 2008-11 PHPNW08 folder hierarchy, so each photo within it, such as the one of Johanna and Mike, needs a keyword of “PhotosExport>Conferences & Meetups>2008>2008-11 PHPNW08>Published”. (I added “PhotosExport>” so that these keywords are easy to identify.)

Obviously, I didn’t do this by hand as it would take ages and be prone to error, so I wrote a script to do it for me!

The KeywordAlbum.applescript should be placed somewhere useful such as ~/Library/Scripts/Applications/Photos. I ran it by opening it in Script Editor and pressing the “play” toolbar button.

This is the key loop:

We iterate over all albums and for each album we call getAlbumKeyword() to get the hierarchical keyword containing this album’s name and all its parents. Once we have the name, we can iterate over every photos in the album and add our keyword. See the gist for the full details.

After running the script, all my photos in Photos now have a keyword that starts with “PhotosExport>” for each album that they belong to.

When imported into Lightroom Classic, the “>” is treated as a nesting separator, so they appear in the Keywords panel like this:


Lr photosexport keywords

This image of Lightroom Classic’s Keyword List panel shows the Published keyword that maps to the Photos album from earlier within the PhotosExport -> Conferences & Meetups -> 2008 -> 2008-11 PHPNW08 hierarchy of keywords.

We now need to convert that keyword hierarchy into collections and collection sets which are Lightroom Classic’s terms for albums and folders.

Unfortunately, Lightroom Classic isn’t scriptable with AppleScriipt, but does supports plug-ins written in Lua, so I wrote a plug-in to do this work. My collection-creator plug-in creates collections within nested collection sets from a keyword hierarchy and as a result, I was able to get the same set of folders and albums in Lightroom Classic that I had in Photos.


Lr phpnow08 collection

With a solution found for transferring folder and albums, we now turn our attention to exporting the photos themselves.

Exporting the photos from Photos

It is trivial to export all your original photos from Photos along with the metadata (title, description, keywords) in an XML sidecar file. You can then import these into Lightroom Classic, but it will lose all your edits (including crops) and for JPEGs, you will also lose all your metadata as Lightroom Classic doesn’t read XML sidecar files for JPEGs.

This is not ideal and we can do better.

Exporting JPEG photos

I don’t use RAW+JPG when shooting RAW, so all JPEGs I have in Photos are originals from my phone or a small camera. For these, we need to export them all as new JPEGs out of Photos so that they contain any metadata (title, description, keywords) that may be set.

The easiest way to do this is to create a smart album called “All Non-RAWs”:


Photos sa non raws

As we can’t select just JPEGs we select for all non-RAW files which will include any PNGs etc that may be in our library.

To export, we select all photos in the smart album, and choose the File -> Export X Items… menu item (where X is the number of photos you have selected). This option exports the photos as processed by Photos.

This dialog will be displayed:


Photos export processed

Expand the Photos section and select JPEG, with maximum quality, most compatible colour profile at full size. Check every box in the Include section and then press Export. Choose a folder to save to and it will create a set JPEG files with the metadata embedded within each one.

These can be imported into Lightroom Classic.

Exporting RAW photos

Exporting RAWs is more complicated as the edits I have made in Photos cannot be interpreted by Lightroom Classic.

We have two choices:

  1. Import all original RAWs into Lightroom Classic and also import a set of JPEGs for the edited RAWs
  2. Import all unedited original RAWsLightroom Classicand also import a set of JPEGs for the edited RAWs. Archive the edited original RAWs separately.

Option 1 is the belt-and-braces solution, but means that for every edited RAW photo, you have two separate, unconnected image files in Lightroom Classic as it doesn’t handle RAW+JPG as I would hope and ignores the JPEG completely unless unless the “Treat JPEG files next to raw files as separate photos” option in Preferences is checked. (i.e. if you go this route, ensure that preference is checked!)

I didn’t want an additonal 13,800 images in my new Lightroom Classic catalog, so I went with option 2.

The approach I took was to assume that I don’t want to re-edit any photo that I previously edited in Photos so I want to import the processed JPEG for these RAW files and will not have the original RAW in Lightroom Classic.

I will however archive the original RAW files, so that if I ever did decide that I would like to re-edit a previously edited photo, I can extract the original file from my archive, import it into Lightroom and then re-edit.

To achieve this, I did these exports from Photos for importing into Lightroom Classic:

  1. All unedited RAWs as originals with XML sidecars
  2. All edited RAWs as processed JPEG

This gives me all RAW files that have not been edited with their metadata and JPEGs of all the RAWs that I have edited with their metadata.

Export 1: The smart album in Photos for unedited RAWs is:


Photos sa unedited raws

To export as originals with XML side car files, select all photos in the smart album and choose File -> Export -> Export Unmodified Original of X Photos… (where X is the number of photos you have selected). This dialog is then displayed:


Photos export originals

Ensure that you select Export IPTC as XMP from the next dialog and then press Export, choose a folder and it will then create a set of RAW files where each one has an XML sidecar file with the same name.

Export 2: For the edited RAWs that we want as JPEGs, the smart album criteria is very similar:


Photos sa edited raws

I then selected all the photos in the smart album and added a new keyword edited-before-lightroom to them. This took a while, but I’ll need it so that I’ll know if there’s a RAW file in the archive that I should use if I ever want to re-edit in Lightroom Classic

To export select all photos in the smart album and, as with exporting all our JPEGs, choose the File -> Export X Items… to create a set of maximum quality, full size JPEG files with embedded metadata. This creates a folder full of JPEG files with the metadata embedded within each one.

Export 3: I created a smart album for all non-RAW files:


Photos sa non raws

As with export 2, I exported using File -> Export X Items… to create a set of JPEG files with embedded metadata.

The photos from all both of theses exports are then imported into Lightroom Classic.

Finally, I exported the photos in “Edited RAWs” smart album again, but this time using the File -> Export Unmodified Original of X Photos… menu item in order to create an archive of the original RAW files for the photos that were edited in Photos and are now JPEGs in Lightroom Classic. These are stored on my NAS for safe keeping.

And I’m done!

To conclude

Changing database backed photo management tools is quite a lot of work if you want to keep your album organisation and also the photo edits you did. It would be a lot easier if there was a common standard for keeping folder/album information in a photo’s metadata. It would be even better if there was a common way to store non-destructive edits in a cross-application manner, but I can’t see that ever happening!

I should also point out that if the new Lightroom (not Lightroom Classic) is what you want, then you’re good to go as Adobe provide a migration button for you. If you want to use Lightroom Classic, then this is the process I used.

As a final thought, although, I’ve talked about migrating from Photos to Lightroom Classic, the basic principles hold true for migrating to and from any photo management app. It’s much more problematic if one of the applications isn’t scriptable though!

3 thoughts on “Migrating to Lightroom Classic from Apple Photos

  1. Thank you for sharing this information, Rob! I ran your KeywordAlbum.applescript on my Photos library consisting of 23 819 images across 307 albums. It worked like a charm, even with Norwegian letters and special characters in file- and album names. Zero errors. I have a mixture of RAW + JPEG and PNGs from different cameras, including Nikon, Canon and Leica. You really saved me a lot of hassle.

  2. Your fine work here will save me countless hours as I recover two corrupted very large (220 gigs & 410 gigs) old iPhoto libraries from a Synology NAS I used to archive my brothers iMacs data before one of them had an unrecoverable hard drive failure. The iMacs were both acting badly a couple months before the ultimate failure, which prompted me to buy his family a small NAS and do an archive backup during a family visit. My brother is a fine photographer, but rather busy as a primary care doc attending to his patients on the frontlines of CV-19 pandemic in Boston, so I wanted to take on this task for him.

    After much work I have recovered and converted his old iPhoto libraries to newer Photos versions and with your guide and tools will now work to migrate them into Lightroom Classic. Everything is now backed up onto multiple drives on my collection of NAS's. Will be using a vanilla install i9-9900 cpu Hackintosh I built to process the Photos –> Lightroom migration, otherwise my old mid-2010 MBP would find the task a bit daunting.

    Thank-you again for developing this workflow. Best regards.

    — stay safe.
    — mark in Seattle

  3. Your KeywordAlbum.applescript worked pretty well on my first test of an Apple PhotosLibrary. It added the expected keywords: PhotosExport>some-album-name, to the jpeg files. It ignored photos and albums inside PhotoLibrary folders, so I repeated the process with a fresh copy of the test PhotosLibrary, this time moving all the Albums into the same root level of Photos –> Albums.

    One question if I may: when I leveled the Album structure, and even before doing so, multiple Albums can point to the same original jpeg photo file. So not unexpectedly KeywordAlbum.applescript iterating over all the Albums sometimes created multiple keyword entries inside a jpeg file:

    a JPEG photo file:
    Keywords:
    PhotosExport>some-album-name
    PhotosExport>another-album-name

    Was wondering how the Adobe Lightroom Classic plugin code will deal with multiple "PhotosExport>" keywords. If it stores a copy of the JPEG file inside a hard drive folder with the same name as the original Apple Photos Album name then that would be workable, even better … maybe if it stores the JPEG in the hard drive folder created first and any other "PhotosExport>" keywords associated with the JPEG file get a symbolic reference … or the Lightroom Classic equivalent placed inside the second Lightroom folder.

    Took some effort to prevent Apple Photos from processing all the previous Photo Libraries it knew about, when I really only wanted it the KeywordAlbum.applescript to process only my test Photo Library. No harm was done, because I stopped the script before it could do that. My assumption was the script would only process the Apple Photos "system library" which my test PhotosLibrary was designated as. Not clear how Apple intends a user to remove PhotoLibrarys from it's list of available libraries, so I disconnected the internal hard drive holding the non-test libraries, leaving only the test Library visible to the system.

    Thank-you once again for providing your applescript and LR plugin.

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *