Build Dazz Cam

YESreplaces $6.99/mosaves $83.88/yrback to the verdict

0%0 of 20 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A camera application with a live filtered viewfinder running at frame rate on the graphics processor, a carousel of film looks built from real transforms rather than overlays, full resolution capture applying the identical pipeline, and a develop mode that applies the same looks to photographs you already have.

estimated effort weekendthe files for this build are in the project pack

LanguageSwift 6 with SwiftUI and MetalCaptureAVFoundation with a video data output for preview and a photo output for captureEffectsA Metal shader pipeline parameterised by image dimensionsColourWork in a linear space and convert once at the endStorageSave to the photo library with the original preserved when the user asks

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree if you own a Mac

    Why There is no supported way to build or sign an iPhone application without it.

    Get it Install Xcode from the Mac App Store or developer.apple.com. It is a large download. open ↗

    Verify xcodebuild -version prints 16 or higher

  2. have readyfree if you have one

    Why The simulator has no camera and no graphics processor characteristics worth measuring. Every claim in this build is a device claim.

    Get it Any recent iPhone with a developer profile installed. Free provisioning allows installing your own build for a limited period, which is enough to start.

    Verify A build runs on the device and shows a camera preview

  3. decidefree

    Why The preview and capture pipeline is Metal, and doing this on the processor produces a slideshow rather than a viewfinder.

    Get it Work through a shader tutorial before Phase 1 if you have not written one. The first shader is the hard part; the rest is arithmetic.

    Verify You can write and run a shader that inverts colours on the preview

  4. have readyfree if you build your own, which is also the more interesting work

    Why Shipping a table extracted from another application or licensed for personal use only is a redistribution problem, and it is the most noticeable thing to copy.

    Get it Build your own from photographed colour references, or use tables explicitly licensed for redistribution. Record the source of each.

    Verify Every table has a recorded source and a licence permitting distribution

  5. have readyfree

    Why A look that flatters one scene is easy; the differences appear on a dark room, a bright window, and a face. Those three are where a filter reveals itself as an overlay.

    Get it Shoot a high contrast scene, a flat overcast one, a dark interior and a portrait. Keep them for comparing looks.

    Verify Four reference scenes are captured and used for every look

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- looks(id, name, ordinal, lut_key, grain_params_json, vignette_params_json, leak_params_json, date_stamp)
- captures(id, look_id, taken_at, width, height, original_path, rendered_path, params_hash)
- develops(id, source_asset_id, look_id, rendered_path, at) · applying a look to an existing photograph
- settings(key, value) · selected look, whether to keep originals, date stamp format
- The parameters hash on every capture is what lets a photograph be re-rendered later with the same look, which matters when a look is adjusted.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
PREVIEW_TARGET_FPSrequired30Frame rate the viewfinder holds. Measured on device rather than assumed.
GRAIN_SCALE_MODErequiredrelativeEffects are expressed relative to image dimensions. The alternative is the bug this build is built around.
KEEP_ORIGINALSrequiredtrueWhether the unfiltered capture is saved alongside. True by default, because photographs are irreplaceable.
DATE_STAMP_FORMATrequiredyy MM ddFormat for looks that carry a stamp. Configurable and disableable.
LUT_DIRrequiredResources/LUTsColour lookup tables with their licence file alongside.

The build, in order

  1. A viewfinder that runs at frame rate

    The live preview shows a filtered image without dropping frames.

    1. Feeding a Metal view directly. No conversion through an image object per frame.

      Files Camera.swift

    2. A simple colour transform first. Instrument the per-frame time before adding anything.

      Files Shaders/Base.metal

    3. A call, another camera application, backgrounding. All three end the session.

      Files Camera.swift

    done when · tick each as it passes
    watch out
    • Filtering on the processor rather than the graphics processor drops the preview to a slideshow, and converting each frame through an image object allocates memory every frame which the collector then has to reclaim. Keep the pixel buffer on the graphics processor from capture to display and allocate nothing per frame.
  2. Capture that matches the preview

    The saved photograph looks like what the viewfinder showed.

    1. One shader chain applied to both paths. Two pipelines diverge immediately.

      Files Capture.swift

    2. Relative units throughout. This is the phase's whole point.

      Files Shaders/Effects.metal

    3. Same framing, side by side at full size. Fix every difference before moving on.

    done when · tick each as it passes
    watch out
    • Grain, vignette and light leaks written in pixel units look right on the small preview buffer and wrong at full resolution, and the difference is obvious as soon as someone looks at the file. Express every effect in units relative to the image dimensions and pass those dimensions into the shader.
  3. Looks that are colour transforms

    Each film look is a real transform rather than a coloured overlay.

    1. Undo the transfer function on input, apply, reapply at the end. Everything between is linear.

      Files Shaders/Colour.metal

    2. A real colour transform. Overlays are the thing being avoided.

      Files Looks.swift

    3. Switching updates within a frame or two. A pause here makes browsing looks unpleasant.

      Files LookCarousel.swift

    done when · tick each as it passes
    watch out
    • A semi-transparent coloured overlay is what a filter looks like when it is not a colour transform: it lifts the blacks, flattens contrast and looks the same on every photograph. A lookup table applied in linear space changes colours the way film does, differently depending on what is in the frame.
  4. The date stamp and the deliberately imperfect looks

    A camcorder or disposable look reads as that thing rather than as a filter.

    1. Position and size as fractions. The same rule as every other effect.

      Files Shaders/Stamp.metal

    2. Aberration and falloff increasing towards the edges, which is what real lenses do.

      Files Shaders/Lens.metal

    3. Stamp and scan lines are the two people notice. Compare at full size.

    done when · tick each as it passes
    watch out
    • A date stamp drawn at a fixed pixel size sits in a different place and a different proportion on the capture than on the preview, which is the same resolution problem as the effects and the one most likely to be forgotten because it feels like a text overlay rather than an effect.
  5. Developing photographs you already have

    A look can be applied to an existing photograph with the same result.

    1. Identical shader chain. A second path for develop mode would diverge from the camera.

      Files Develop.swift

    2. Never in place. This is the rule that protects irreplaceable photographs.

      Files Library.swift

    3. A full resolution photograph can exhaust memory on a phone. Tile with overlap if needed.

      Files Develop.swift

    done when · tick each as it passes
    watch out
    • Overwriting the original when applying a filter destroys the only copy of a photograph, and it is the complaint that ends an application's reviews. Always write a new asset, and make keeping the original the default rather than a setting people have to find.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more photo editing.