Film Negative Inverter

Browser-based C-41 color negative inversion and mask removal.
WEBGL2 // 48MP
NEGASOURCE-PRO
1304×1420
AUTHENTIC 35MM FILM NEGATIVE LOADED
INPUT SOURCE:
EMULSION PROFILES:
FILM CURVE1.55
GAMMA1.85
BLACK POINT0.04
WHITE POINT0.96
SATURATION1.00
MASK RGB
207, 157, 127
💡 Click unexposed film border (sprocket gap) to sample base mask color.100% PRIVATE CLIENT-SIDE PROCESSING
COLOR PRESETS

Film Emulsion Profiles

Tonal curves and gamma parameters for common color and B&W stocks

Kodak Portra 400PROFILE

Wide dynamic range with gentle highlight roll-off and natural skin tone rendition.

CURVE: 1.45–1.60GAMMA: 1.80
Kodak Gold 200PROFILE

Warm golden highlights and punchy primary color saturation suited for daylight exposures.

CURVE: 1.45–1.60GAMMA: 1.80
Fujifilm Superia 400PROFILE

Clean emerald greens, cool sky tones, and crisp edge contrast.

CURVE: 1.45–1.60GAMMA: 1.80
Ilford HP5 Plus 400PROFILE

Traditional silver halide monochrome with dense shadow separation and rich midtone gray gradient.

CURVE: 1.45–1.60GAMMA: 1.80
COLOR PIPELINE

Color Science & Pipeline

Logarithmic mask subtraction, 40×40 outlier-filtered sampling, and GPU tone mapping

LOGARITHMIC MASK SUBTRACTION EQUATION

Color negative film emulsion attenuates transmission exponentially according to optical density: D = log₁₀(1 / T). Linear inversion (255 - X) fails because the orange mask dyes (colored couplers) skew the green and blue channels. Inverting in optical density space eliminates color casts:

// 1. Optical Mask Subtraction & Film Response Curve
vec3 inverted = pow(max(vec3(0.0), 1.0 - (pixel / mask)), vec3(u_filmCurve));
// 2. Dynamic Level Stretching (Black / White Points)
vec3 leveled = clamp((inverted - u_black) / (u_white - u_black), 0.0, 1.0);
// 3. Gamma Power Correction & Saturation Compensation
vec3 gammaCorrected = pow(leveled, vec3(1.0 / u_gamma));

ZERO-SERVER SECURITY

All rendering runs on your device's local GPU using WebGL shaders. No imagery is ever transmitted to remote servers.

LOCAL-FIRST SANDBOX
NO EXTERNAL API // ZERO CLOUD LOGS
01 // SPEC

Logarithmic Orange Mask Subtraction

Negatives absorb light exponentially following the Beer-Lambert law. Dividing pixel values by the base mask in optical density space eliminates cyan-blue color casts without clipping shadows.

02 // SPEC

40×40 Precision Sampling

Samples an area of 40×40 pixels with outlier rejection to smooth out film grain noise and calculate an accurate reference white balance.

03 // SPEC

High-Resolution Macro Scans

Handles up to 48MP camera digitizations (macro lens DSLR/mirrorless captures) at native texture resolution.

04 // SPEC

100% Client-Side Privacy

All rendering runs on your device's local GPU using WebGL shaders. No imagery is ever transmitted to remote servers.

WORKFLOW

Workflow

Four steps from negative capture to positive export

01

Load Negative Image or Camera

Position your film over a uniform backlight or drag & drop a high-resolution raw scan.

02

Sample Base Orange Mask

Click 'Sample Mask' and pick an unexposed film border between frames to register the base color.

03

Select Emulsion & Tune

Choose a film preset and refine gamma, black point, and curve exponent in real-time.

04

Export Positive Image

Click 'Export Positive' to download the processed full-resolution JPEG.

FAQ

Technical FAQ

Fundamentals of analog color negative digitization

Why does a simple RGB color inversion (255 - X) fail on color negatives?

C-41 color negative films contain colored couplers that form an integral orange mask to compensate for imperfect dye absorption in the green and blue sensitive layers. Simple linear inversion produces heavy cyan and blue color casts with severely clipped shadows. True inversion requires dividing by the mask in logarithmic density space.

What is the recommended lighting setup for camera scanning?

Use a diffused light source with a Color Rendering Index (CRI) of 95 or higher (such as dedicated CRI 95+ LED panels or a high-resolution tablet screen set to full white). Keep camera ISO at base level (ISO 100) and shoot in a dark room to avoid ambient surface reflections.

Are my film scans uploaded to any server?

No. The entire inversion pipeline is compiled into WebGL fragment shaders and runs locally on your browser's GPU. Nothing leaves your machine.