Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<img src="Sources/LUTzy/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png" width="96" alt="The LUTzy icon: an RGB colour cube on a dark tile">
<img src="Sources/LUTzy/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png" width="96" alt="The LUTzy icon: an RGB color cube on a dark tile">

# LUTzy

A macOS app that applies `.cube` LUTs to RAW and other images. It can also build a LUT from a RAW + JPEG pair.

SwiftUI and Core Image, no third-party packages. macOS 26 to run, [Xcode 27 to compile](#build).

A 3D LUT is a table with a colour at every lattice point. The photo's colours are looked up in it, interpolated between the nearest points, and replaced. That is the whole trick, and it is why a LUT can be a look but never a sharpen or a blur.
A 3D LUT is a table with a color at every lattice point. The photo's colors are looked up in it, interpolated between the nearest points, and replaced. That is the whole trick, and it is why a LUT can be a look but never a sharpen or a blur.

<img src="docs/images/lut-cube.svg" width="720" alt="Two colour cubes. On the left, a regular lattice of coloured dots. On the right, the same dots after a LUT: shadows lifted and cooled, highlights warmed.">
<img src="docs/images/lut-cube.svg" width="720" alt="Two color cubes. On the left, a regular lattice of colored dots. On the right, the same dots after a LUT: shadows lifted and cooled, highlights warmed.">

## Features

Expand All @@ -32,7 +32,7 @@ A 3D LUT is a table with a colour at every lattice point. The photo's colours ar

The JPEG is treated as a look (the manufacturer's color science, or whatever picture profile was on). LUTzy writes the difference against a neutral RAW develop. Same frame required — aspect within 1%. Pixel size can differ.

<img src="docs/images/derive.svg" width="720" alt="RAW is developed neutrally and the JPEG decoded; the pair is aligned, edges masked, sampled, and filled into a 33-cubed cube that is written as a .cube file and a report.">
<img src="docs/images/derive.svg" width="720" alt="RAW is developed with neutral settings and the JPEG decoded; the pair is aligned, edges masked, sampled, and filled into a 33-cubed cube that is written as a .cube file and a report.">

The result previews on the current image and stays in memory until **Save to LUT Folder…**.

Expand Down
2 changes: 1 addition & 1 deletion docs/images/lut-cube.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion scripts/render-readme-graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def lut_cube_svg():
out.append(f'<path d="M318 152 H398" stroke="{INK}" stroke-width="1.2" fill="none" stroke-linecap="round"/>')
out.append(f'<path d="M392 146 L399 152 L392 158" stroke="{INK}" stroke-width="1.2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>')
out.append(f'<text x="358" y="140" text-anchor="middle" fill="{INK2}" font-family="{MONO}" font-size="12">.cube</text>')
out.append(f'<text x="190" y="304" text-anchor="middle" fill="{INK2}">every colour a photo can hold</text>')
out.append(f'<text x="190" y="304" text-anchor="middle" fill="{INK2}">every color a photo can hold</text>')
out.append(f'<text x="530" y="304" text-anchor="middle" fill="{INK2}">where the LUT sends each one</text>')
out.append('</svg>')
return '\n'.join(out)
Expand Down
Loading