Skip to content

PixelLoupe 1.2.0

Latest

Choose a tag to compare

@github-actions github-actions released this 25 Oct 19:59
· 47 commits to main since this release
cf710f1

What and why

1.1 made PixelLoupe workable away from the originals and gave it a proper import window. 1.2 covers the next things Lightroom Classic users reach for: finding photos fast, putting them on a map, culling a shoot, and getting finished photos out to Flickr or a folder that stays in sync. Along the way it adds a contact sheet, a Before/After view, an Aperture-style Gray appearance and a batch of fixes.

Publishing: Hard Drive and Flickr (#62–#70)

  • Window ▸ Publishing Manager… sets up publish services, laid out like Lightroom's. There are two kinds:
    • Hard Drive: publishes to a folder (and optional subfolder). Re-publishing overwrites the photo's own file.
    • Flickr: sign in with Authorize, which opens flickr.com. The sign-in is kept in your Keychain, never in the catalog. You can also set the title source, privacy (Public, or Private with Family/Friends), safety level, content type and "Hide from public site areas".
  • Every service has the Export dialog's settings: File Naming, File Settings, Image Sizing, Output Sharpening, Metadata and Watermarking. Flickr always uploads JPEG.
  • A Publishing section in the sidebar lists your services. Drag photos onto one to add them. Select a service and the grid groups its photos as New Photos to Publish, Modified Photos to Re-Publish, Published Photos and Deleted Photos to Remove.
  • Publish (in the bar above the grid, or Publish Now in the sidebar) uploads new photos and re-publishes edited ones:
    • On Flickr, a photo whose pixels changed is replaced in place, so it keeps its page, comments and favourites.
    • A photo whose title, caption, keywords, rating or location changed only gets its details updated, with no new upload.
    • Photos you take out of a service are removed at the next Publish, after you confirm. Hard Drive files go to the Trash.
    • Progress and Cancel show in the bottom bar. Photos that fail get a red badge that tells you why, and the next Publish tries them again.
    • If Flickr revokes PixelLoupe's access, Publish stops once and tells you to sign in again, instead of failing every photo.
  • Flickr albums and smart albums. Use Create Album…, Create Smart Album… and Import Smart Collection Settings… (which reads Lightroom .lrsmcol files). Albums appear under the service. Publish only ever adds or removes the photos this catalog put in an album. It never deletes an album on Flickr, and it leaves photos you added on flickr.com alone.
  • Lightroom's publish service menu in the sidebar has Set as Target Collection (so B adds photos to a service), Reset Export Status…, Mark to Republish, Auto Stack…, a color label, and Show in Flickr / Show in Finder.
  • Write Keywords as PixelLoupe Hierarchy, in both Export and Publish, writes nested keywords as Places|Ireland|Dublin. Lightroom reads that and rebuilds the tree. It's off by default.

Assisted Culling and Auto Stack (#57–#61)

  • A new Assisted Culling section in the Library inspector splits the current folder or collection into Selects and Rejects.
    • Click Analyze to measure subject focus, eye focus, open eyes, exposure problems, misfires and documents. It runs in the background and works from the Smart Preview when the original is offline.
    • Choose what counts: Subject Focus and Eye Focus sliders, Eyes Open (with an option for ambiguous cases, such as one blink in a group shot), Exposure Issues, Misfires and Documents.
    • Review filters the grid to Selects, Rejects or All. Moving a slider re-filters at once, with nothing re-analyzed.
    • Apply Flags marks unflagged Selects as Picks and unflagged Rejects as Rejected, in one undoable step. Photos you've already flagged keep their flag.
  • The Assisted Culling Info section shows why the selected photo is a Select or a Reject, with its scores out of 100.
  • Auto Stack… groups bursts and brackets into collapsed stacks, either By Capture Time (a gap from 1 second to 1 hour) or By Visual Similarity (Loose to Strict). A live count shows what you'll get before you commit. The best-scoring Select goes on top of each stack.

Map module and locations (#52–#55)

  • View ▸ Map (⌘3, or ⌥⌘3 as in Lightroom) shows the photos in the current source as pins on Apple Maps.
    • Nearby pins cluster.
    • Hover a pin to see its thumbnail. Click a pin to select its photo; with a cluster, the arrows step through its photos. Double-click a pin to open it in Loupe.
    • A floating bar has Standard / Satellite / Hybrid, a photo count and a zoom slider.
    • The Library Filter and the Library inspector work in Map too.
  • A Location panel in the Library inspector searches for addresses and places as you type. It shows the spot on a small map with a pin you can drag. Apply gives the location to photos that have none, Replace overwrites (asking first if that would replace a location the camera recorded) and Remove clears it. You can also type lat, lon, which works offline.
  • Export now writes the catalog's location to EXIF and XMP. A location you typed or removed in PixelLoupe reaches the exported file, including files sent with Edit In.

Library Filter (#38–#42)

The old filter row above the grid is now Lightroom's Library Filter bar. Show and hide it with \ in Library, or View ▸ Show/Hide Filter Bar, and use ⌘F to jump to its search field.

  • Text: search any field or a chosen one (file name, title, caption, keywords, camera and lens, creator and copyright…). Rules include Contains, Contains All, Contains Words, Doesn't Contain, Starts With and Ends With. Lightroom's !word, +word and word+ work too.
  • Attribute: Flag, Edited/Unedited, Rating, Color label (including custom Lightroom labels), Kind (originals, virtual copies, videos) and Stacked.
  • Metadata: Lightroom's column browser. Choose from 18 kinds (Date, Camera, Lens, Keyword, ISO, Aspect Ratio, Folder…). Each column narrows the ones to its right. You can have up to 8 columns and drag the bar to the height you want.
  • Presets: the built-in Filters Off, Default Columns, Exposure Info, Flagged and Rated, plus your own. Your presets are shared by every catalog.
  • The filter stays on as you move between folders and collections, and is saved with the catalog. When it hides photos, the filmstrip says "42 of 310 photos".

Contact Sheet (#31)

Window ▸ Contact Sheet (⌃⌥⌘C) lays the selected photos (or the whole grid) out on pages with a headline, description, page numbers, borders, shadows and a caption you choose. Generate… saves a 300 ppi PDF. The page size, orientation and the rest of the layout are remembered.

Develop

  • Before/After (#34): View ▸ Before/After offers Left/Right (Y), Top/Bottom (⌥Y), Before Only (\) and Split Screen (⇧Y), with Lightroom's keys. Press the same key again to go back. Side by side, both photos zoom and pan together.
  • White balance preview (#49): scrubbing through the White Balance pop-up previews each choice on the photo, as the Profile menu already did.
  • Spot Removal (#46):
    • Zoomed in, you can drag to pan.
    • Spots show resize handles when you hover over them.
    • Each row has a delete button.
    • New spots are the same size on screen at any zoom.
  • Masking (#32): each mask's row has its own red delete button, replacing the one at the bottom of the panel.
  • HDR with Previous Settings (⌃⇧H) (#51) merges the selection with your last HDR settings, skipping the preview sheet, like Panorama's ⌃⇧M. If the photos can't be merged (a JPEG in the mix, or different cameras), it says why up front.

Appearance

  • Gray (#50): a fourth choice in Settings ▸ Appearance, after Aperture: mid-gray chrome, dark text and a black matte behind photos.
  • Matte Color (#47) now goes back to the theme's default (10% in Light, 85% in Dark, black in Gray) whenever the appearance switches. The defaults are a little lighter in Light and a little darker in Dark than in 1.1.
  • The right sidebar button (#48) no longer lights up with the accent color, matching the left.
  • The filmstrip's header (folder, count, path, filters) now sits on the window's chrome, not the matte, in every appearance.

Import

  • Sort direction (#37): a button beside the Sort pop-up flips between ascending and descending. It's remembered.

About window (#71)

About PixelLoupe shows just the version (Version 1.2.0). Hold ⌥⌘ when you choose it to see the build number along with the credits. The Welcome window still shows both.

Fixes

  • Virtual copies (#56): a new virtual copy no longer shows up as an empty JPG that can't be opened, rated or removed. Removing only virtual copies no longer offers Delete from Disk.
  • Third-party profiles (#35): a third-party profile chosen in the Profile menu, or applied by a preset, now stays applied. Before, it reverted when the menu closed. Photos imported from Lightroom with a third-party profile keep it too. Photos edited before 1.2 never saved the profile, so choose it again once.
  • Masks (#32): moving or resizing a linear or radial mask, then touching one of its sliders, no longer snaps the mask back to where it started.
  • Folders (#36): copying an import into a folder that's already in the catalog now nests the new folders inside it, instead of at the top level. Update Folder Location… also accepts the folder a moved folder now sits in, and moves it to the right place in the sidebar. To repair a folder that 1.1 put at the top level, use Update Folder Location… on it.
  • Stacks (#61): clicking a stack's badge expands and collapses it again. This was broken for every stack.
  • Merges (#51): with Create Stack on, the merged photo is now selected afterwards.
  • Import window (#33): the All / New / Destination filter stays centered under Copy / Add.
  • Secrets (#62): builds since a project change in 1.1 development copied the local .env file into the app bundle. Service keys are now compiled in, masked, and the release script refuses to package any .env file. No secrets were committed to the repository.

How It Works

  • Catalog model, v15 → v20. Five lightweight, automatic migrations:
    • v16: numeric photo locations, both the file's and your override (#52).
    • v17: culling scores (#57).
    • v18: publish services and published photos (#63).
    • v19: a service's color label (#69).
    • v20: publish albums (#70).
  • Locations are stored as numbers, so the Map can show thousands of pins without opening a single file. A photo keeps the file's location and your override separately, so Revert, Replace's undo and export can always reach the camera's value. Older catalogs are brought up to date in the background after they open (LocationBackfill). Most photos are handled with one batch update and never opened. Files on offline drives are tried again the next time the catalog opens.
  • Assisted Culling uses Apple's Vision framework for faces, eye landmarks, saliency and an aesthetics score. Focus is measured as edge width on the crispest parts of the subject and eyes, at 2,560 px, so a photo scores the same whether it's measured from its original or its Smart Preview. Raw scores are stored, so the panel's sliders only change a Core Data predicate. The grid, the counts, Apply and the Info panel all use the same rules.
  • Publish state (New, Modified, Published, Deleted) is worked out from each photo's edit date and a fingerprint of its published metadata, not stored as a flag (ADR 0002). An edit made through any path, including undo, Lightroom import or metadata sync, can't leave a photo looking published when it isn't. Results are saved as each photo finishes, so a cancelled Publish keeps what it did.
  • Flickr sign-in is OAuth 1.0a through ASWebAuthenticationSession, asking for delete permission so Publish can remove photos. Requests that hit rate limits, server errors or dropped connections are retried after 2, 5 and 15 seconds, or after Flickr's Retry-After. The Flickr API key is compiled into the app, masked (ADR 0001).
  • The Publishing Manager and the Export dialog now share one settings form (ExportSettingsForm), so they behave the same.
  • The Library Filter keeps each mode's criteria separately. Turning a mode off keeps its settings, and turning it back on restores them. The Metadata columns are counted with GROUP BY queries on a background context, and only while they're showing.
  • The Map fetches pins with the grid's own filter on a background context, and refetches only while Map is showing.
  • Before/After builds Before Only and Split Screen as a single image in the usual Develop pipeline, so zoom, the loupe, clipping overlays and full-resolution detail all work unchanged. The "before" is the photo's default settings with its crop and Transform kept, so the two halves line up.
  • Contact Sheet draws its preview and its PDF with the same layout and drawing code, so they can't drift apart.

Decisions and trade-offs

  • Catalogs opened in 1.2 can't be opened in 1.1. The model migrations are one-way. Back up your catalog before upgrading if you might need to go back.
  • Publishing
    • Changing a service's rendering, naming or title settings asks whether to Re-Publish All or Leave As Is. Privacy and safety changes don't ask, and they're never changed on Flickr after the first upload.
    • A re-publish keeps its file name even if the naming template changed, so links to the file don't break.
    • You can't change a Flickr service's account once it has published photos. Another account means another service.
    • Moving a keyword in the tree doesn't mark published photos Modified. Otherwise every published photo with keywords would have turned Modified the moment 1.2 installed. Use Mark to Republish if it matters.
    • Album photos are in the order they were added, and the album cover is picked when the album is made.
    • Videos can't be published yet.
    • Flickr has no SF Symbol, so its services show a globe.
  • Assisted Culling
    • Focus is judged at 2,560 px, so "sharp" means sharp on a large display, not at 100%.
    • People looking down can read as closed eyes. Use "Select ambiguous photos" if that catches you out.
    • Photos inside a collapsed stack aren't counted, analyzed or flagged until the stack is expanded. Because Auto Stack collapses its stacks, the counts and Apply Flags afterwards cover only each stack's top photo, which is the best Select.
    • Auto Stack only joins neighbouring photos in capture order. It won't gather similar shots that have others between them.
  • Map and locations
    • Map camera positions are remembered per source while the window is open, but not across launches.
    • The Location panel doesn't fill in City / State / Country, and doesn't edit altitude or direction.
    • Setting a location drops the original's altitude and direction from exports, since they described a different place.
    • Photos still waiting for the background location pass get their pins when it reaches them.
  • Library Filter
    • Filter presets are app-wide, as in Lightroom. The bar's current state is saved per catalog.
    • The "Location Columns" built-in is left out.
    • Text search can't reach the extra IPTC fields.
  • Before/After always compares against the default settings. There's no Lightroom-style custom "before" state.
  • Gray is Light Mode underneath with darker chrome, so in Gray the sidebars are flat panels rather than Liquid Glass.
  • Spot Removal's brush size isn't saved between launches.
  • Contact Sheet has no Print yet, only a PDF.

How tested

  • The full unit suite passes: 1,216 tests in 216 suites, built with warnings as errors, as CI runs it on main (up from 956 tests in 1.1). CI was green at the tag after #71 fixed five Publishing warnings and a test that depended on the runner's screen size.
  • New test suites:
    • Publishing: PublishingTests, PublishingManagerTests, PublishLibraryTests, PublishAlbumTests, FlickrAuthTests, FlickrPublishTests, KeywordHierarchyExportTests, SecretsTests.
    • Culling: CullingAnalyzerTests, CullingAnalysisTests, CullingCriteriaTests, CullingInfoTests, AutoStackingTests.
    • Locations: PhotoLocationTests, MapModuleTests, LocationPanelTests.
    • Library Filter: FilterBarTests, FilterPresetTests.
    • Other: ContactSheetTests, BeforeAfterTests.
    • Many existing suites gained tests for the fixes. Most fixes have a test that fails without the fix.
  • Migration from a real v15 store with typed GPS, and from v17 to v18, is covered by tests.
  • Assisted Culling was tuned on 211 real RAW files (Sony, Fujifilm, DNG), with no false documents or misfires in the final settings. Auto Stack's similarity thresholds were set from measured distances between real photo pairs.
  • Flickr: signing was checked against Flickr's documented base string and against openssl. Live calls to Flickr (a request token and flickr.test.echo) were accepted. Upload, replace, metadata, delete and album calls are tested against a stubbed Flickr.
  • Hard Drive publishing is tested end to end with real JPEGs.
  • The README has new or updated sections for every new shortcut and feature.

Not tested / check by hand

  1. Upgrade: open a copy of a large 1.1 catalog with geotagged photos. It should open as fast as before, and its locations should fill in shortly after.
  2. Flickr, with a real account: sign in, publish, edit and re-publish, update a caption only, remove a photo, then work with albums and smart albums. Upload, replace and the album calls haven't been run against flickr.com.
  3. Assisted Culling on a large real shoot: Analyze speed, grid scrolling while it runs, photos with closed eyes, and real documents (receipts, whiteboards). The samples had none of the last two.
  4. Map with a large geotagged catalog: speed, clustering, hover popovers, and the glass bar over Satellite imagery.
  5. Location search, which needs Apple's servers. Check the offline message with Wi-Fi off.
  6. Gray in the windows not yet looked at: Import, Export, the contact sheet, sheets and the secondary display.
  7. Before/After and Split Screen with large RAW files. They decode the photo twice per frame.
  8. Contact Sheet generated from a large set of RAW files: speed and PDF size.
  9. UI tests: testImportLightroomCatalogIsOfferedInTheWelcomeWindowAndFileMenu fails locally with "Failed to terminate", on unmodified main too, and CI skips UI tests.