The channel formula that powers an RGB color inverter is output red equals 255 minus input red, output green equals 255 minus input green, and output blue equals 255 minus input blue, applied to every decoded pixel while alpha is copied unchanged. For readers searching for a way to invert image colors across multiple files, this deterministic byte operation means the same transformation can be repeated reliably for each image in a batch — black becomes white, white becomes black, red becomes cyan, green becomes magenta, and blue becomes yellow. The Invert Image Colors tool implements exactly that rule in the browser: pick one PNG, JPEG, GIF, or WebP file, wait for byte-container detection and real browser decoding, run the inversion, and download a still PNG. Because each file is processed in its own session inside the current tab, a bulk or multiple-images task is handled by repeating the single-file workflow once per image, with no upload step between iterations. The rest of this article walks through the channel mapping, the hard size limits, the exact step sequence, and the privacy guarantees that make a local browser inverter practical for batch color inversion.

The Channel Formula Applied to Every Pixel
For readers who want a precise definition, the RGB inversion formula is straightforward and byte-level: for every pixel that the browser decoder exposes, the tool replaces red with 255 minus input red, green with 255 minus input green, and blue with 255 minus input blue. Alpha is copied unchanged, including semi-transparent values. Because each channel is processed independently, the operation is commutative and idempotent in a useful sense: applying it twice returns the same decoded byte values, so a user does not have to worry about accidentally double-inverting a batch by clicking the run button twice on the same file.
A worked example confirms the arithmetic. A pixel decoded as RGB(120, 50, 200) becomes RGB(255 − 120, 255 − 50, 255 − 200) = RGB(135, 205, 55), a yellow-green shade. The same operation also defines a small, memorable set of color pairs that beginners rely on: black becomes white, white becomes black, pure red becomes cyan, pure green becomes magenta, and pure blue becomes yellow. The table below lists those canonical pairs alongside an intermediate and a near-mid value so the relationship is visible at a glance.
| Input color name | Input RGB | Output RGB | Output color name |
|---|---|---|---|
| Pure black | (0, 0, 0) | (255, 255, 255) | Pure white |
| Pure white | (255, 255, 255) | (0, 0, 0) | Pure black |
| Pure red | (255, 0, 0) | (0, 255, 255) | Pure cyan |
| Pure green | (0, 255, 0) | (255, 0, 255) | Pure magenta |
| Pure blue | (0, 0, 255) | (255, 255, 0) | Pure yellow |
| Worked example | (120, 50, 200) | (135, 205, 55) | Yellow-green |
| Near-mid gray | (128, 128, 128) | (127, 127, 127) | Near-mid gray |
Why a One-File Browser Inverter Fits a Bulk Workflow
The contract for the tool is built around one image at a time: file pick, byte-level container detection, browser decoding through createImageBitmap, edge and area validation, full-canvas inversion, preview, and PNG export. None of that means a bulk or multiple-images search is unmet. A bulk workflow is just the same single-file sequence repeated per image: open the tool, choose image one, download image one, choose image two, download image two, and so on through the batch. Each session is independent, so a failure on one file does not poison the others, and there is no upload step in between that could leak a partial batch to a remote server.
This is also a deliberate privacy choice. Reading, detection, decoding, pixel access, transformation, preview, and PNG export all happen inside the current browser tab. The image is not uploaded to Lizely or sent to an external service, and selecting another file increments the job generation, closes the prior ImageBitmap, revokes source and output ObjectURLs, clears old errors and results, and resets busy state so late decodes or toBlob results cannot leak into the next selection. For a deeper dive on the local-processing promise, the How to Invert Colours on an Image Without Uploading It walkthrough covers the same property from a different angle.
Supported Inputs, Output Format, and Hard Limits
The tool accepts four formats and exactly four: PNG, JPEG, GIF, and WebP. The filename extension, the file-picker filter, and the operating-system MIME label are deliberately not trusted as format proof. Instead, the actual ArrayBuffer is checked with a pure structural detector before any Canvas work begins. PNG requires the complete signature, the first IHDR structure, and the terminal IEND; JPEG requires SOI, a following marker, and terminal EOI; GIF requires GIF87a or GIF89a, enough logical-screen structure, and the trailer; WebP requires an exact RIFF byte count, the WEBP marker, and a bounded VP8, VP8L, or VP8X first chunk. Truncated magic bytes and renamed arbitrary files fail before Canvas work. The structural check is paired with a real browser decode: a Blob labeled with the detected MIME must then decode through createImageBitmap and report positive dimensions.
Four interacting limits decide whether the tool can finish the job. The table below states them exactly as the product contract defines them.
| Limit | Threshold | Where it is enforced |
|---|---|---|
| Input file size | ≤ 15 MiB | Reported File size before reading; actual ArrayBuffer length after reading |
| Decoded edge (width or height) | ≤ 8,192 pixels | After createImageBitmap reports dimensions |
| Total pixel area | ≤ 24,000,000 pixels | After createImageBitmap reports dimensions |
| Output PNG | ≤ 32 MiB | After HTMLCanvasElement.toBlob returns a Blob |
Exact boundaries are accepted; one byte, one edge pixel, or one pixel-area step beyond them is rejected. These independent limits matter because compressed inputs can expand to large pixel buffers and long narrow images can remain below an area limit while exceeding practical Canvas dimensions. Nothing is silently resized, cropped, sampled, or partially processed, and the output is always a complete PNG.
How to Invert Colors Across Multiple Images
Each file goes through the same three-step flow inside the tool. To process a batch, repeat the steps for the next file in your batch.
- Choose a PNG, JPEG, GIF, or WebP file from the file picker and wait while the browser reports the file size, detects the byte container, decodes the initial frame through createImageBitmap, and validates the width, height, and total area. If the file fails any of those checks, no inversion runs and the next file can be picked without resetting the tab.
- Once the source preview is visible, run the inversion. The tool reads every RGBA slot that Canvas exposes, applies 255 − R, 255 − G, 255 − B with alpha copied unchanged, puts the matrix back, and renders a natural-size PNG preview beside the source so the user can compare side by side.
- Confirm the displayed dimensions and the reported output byte size, then download the still PNG. Selecting another file at any point increments the job generation, revokes the prior source and output ObjectURLs, and resets busy state, so late decodes or toBlob callbacks from the previous file cannot publish into the newer selection.
For a batch of similar files — a folder of product photos, a set of UI screenshots, a stack of scanned sketches — the practical rhythm is to sort the batch, run each file through steps 1 to 3 in turn, and store the downloaded PNGs in a matching folder. Because the rule is exact and deterministic, two runs of the same file produce the same bytes.
What Stays the Same and What Changes
The byte-level inversion is exact, but the output is still a different file from the input. The transformation is a visual effect, not a metadata-preserving conversion. Alpha is copied unchanged, including semi-transparent values, and every RGBA slot exposed by Canvas is processed, including RGB slots whose alpha is zero. However, fully transparent color is invisible, and a browser decoder or Canvas may normalize hidden RGB before getImageData returns it. The tool transforms the bytes Canvas actually supplies; it cannot recover hidden source-file channel data that never reaches ImageData. EXIF, GPS, comments, ICC profiles, and other source metadata are not preserved by Canvas export, so keep the original whenever those fields matter.
Animated GIF and animated WebP inputs use the browser-decoded initial frame and become one still PNG. Later frames, timing, loops, palettes, and disposal behavior are not preserved. PNG can also be larger than a JPEG, GIF, or WebP source, especially for photographs or noisy images, which is why the input and output budgets are intentionally separate. The tool is not film-negative restoration: it does not linearize gamma, model perceptual complementary colors, remove an orange mask, balance scanned film, correct exposure, or perform tonal grading.
Privacy and Local Processing for Sensitive Batches
The privacy promise matters more for a bulk workflow than for a single image, because a batch may contain drafts, client work, or unreleased product shots. The processing pipeline never leaves the browser tab: file reading, structural detection, ImageData processing, preview rendering, and PNG export all run locally. No upload, no external service, no remote log of which file was processed. Successful decoding is not malware analysis, content moderation, authorship verification, or proof that an image is safe or truthful, so a local decode should still be combined with the usual care when the batch comes from an untrusted source.
Cleanup is part of that guarantee. Synchronous Canvas export failures, ObjectURL creation failures, and a null toBlob callback result all enter the same guarded failure path, clear busy state, and leave no old download visible. Unmount closes the bitmap and revokes every remaining URL, and the same cleanup is exercised through React Strict Mode effect setup and cleanup cycles so a stale download from a previous file will not appear after a new file is selected.
When the Bulk Workflow Stops or Rejects a File
Because each file is validated independently, a failure on one file does not abort the batch. The most common rejection reasons are easy to recognize. A file that fails the byte-container check — truncated magic bytes, a renamed BMP or TIFF, a corrupted WebP, or an unsupported format — is rejected before any Canvas work and never enters the preview stage. A file that decodes cleanly but blows past 8,192 pixels on either edge, or exceeds 24,000,000 pixels in total area, is rejected after decoding. A file above 15 MiB is rejected before reading, and the actual ArrayBuffer length is also checked afterward so a file that lies about its size cannot slip through.
Two structural details are worth flagging for batch work. First, a long narrow image can stay under the area limit while exceeding the 8,192-pixel edge limit, so the two checks are deliberately independent and both must pass. Second, compressed inputs can expand to large pixel buffers, which is why an area limit is checked in addition to the byte limit. Output has its own budget: a Canvas that encodes to a null Blob, an invalid size, or a Blob above 32 MiB fails before a result URL is published, so the download button never points at a partial or oversized file. The output is never truncated or silently changed to a lossy format, and the input and output budgets are kept separate on purpose.