[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-93333":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":15,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":16,"compositeScore":17,"rankGlobal":9,"rankLanguage":9,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":9,"pushedAt":9,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":14,"starSnapshotCount":14,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},93333,"pixel-art-fixer","Retro-Diffusion\u002Fpixel-art-fixer","Retro-Diffusion","Convert images into pixel art",null,"Python",163,13,104,0,49,10,68.34,"MIT License",false,"main",true,[],"2026-07-22 04:02:08","# Pixel Art Fixer\n\n![Pixel Art Fixer by Retro Diffusion](docs\u002Fimages\u002Fbanner.png)\n\nConvert fake \"pixel art\" into real, grid-aligned pixel art. Image processing only, no model required.\n\n### ➜ [**Try the Pixel Art Fixer on Retro Diffusion**](https:\u002F\u002Fretrodiffusion.ai\u002Fpixel-art-fixer)\n\nNo install, no setup. Drop an image in your browser and get true pixel art back, free.\n\n![Before and after: fake pixel art converted to true pixel art](docs\u002Fimages\u002Fbefore-after.png)\n\nImage generators, upscalers, and lossy pipelines happily produce pictures that\n*look* like pixel art but aren't. The \"pixels\" drift off the grid, blur into\ntheir neighbors, sit at some awkward non-integer size, and the file is stored at\n10x the resolution the art actually contains. Pixel Art Fixer recovers the\npseudo-pixel grid those images were drawn on and rebuilds each cell as exactly\none true pixel, at the native resolution the art was always meant to be.\n\nIt is built and maintained by [Retro Diffusion](https:\u002F\u002Fretrodiffusion.ai), the\nAI pixel art generator designed by working pixel artists.\n\n## The problem\n\nA \"true\" piece of pixel art is a small grid of deliberate, hand-placed pixels.\n\"Fake\" pixel art is anything that imitates the look without the structure:\n\n- **Off-grid cells.** The implied pixels don't line up to a clean lattice, and\n  the grid often drifts in scale across the image.\n- **Non-integer cell size.** A cell might be 6.38 pixels wide, not 6, so no\n  simple integer downscale lands on it.\n- **Mush and anti-aliasing.** Cell edges are blurred, dithered, or smeared by\n  bilinear resampling, so there are no crisp boundaries to snap to.\n- **Wrong resolution.** A 32x32 sprite arrives as a 1024x1024 PNG with thousands\n  of near-duplicate colors and no clean alpha.\n- **Compression damage.** JPEG's 8x8 block lattice fights the real art grid.\n\nNone of these can be tiled, palette-swapped, animated, or edited pixel by pixel\nuntil they are converted back to real pixels.\n\n## Why existing tools fall short\n\n- **Naive nearest-neighbor or fixed-integer downscaling** assumes one global,\n  integer-sized cell and a phase-0 origin. Real fake-pixel-art violates all\n  three assumptions, so a fixed grid slices straight through cells.\n- **\"Pixel snapper\" utilities** detect a single dominant period and snap to it.\n  That period is very often the *content* scale (a sprite, a texture, a face),\n  not the pixel scale, and it is just as often an octave off (2x or 1\u002F2 the\n  truth scores nearly as well as the truth itself).\n- **Single-heuristic detectors** are brittle: whichever cue they rely on\n  (edges, autocorrelation, FFT peak) fails on a different class of image, and\n  patching one class silently regresses another.\n\n## Why Pixel Art Fixer is state of the art\n\nWithin the space of traditional (non-neural) image processing, this is the most\nrobust converter available:\n\n- **Multiple independent detectors, then consensus.** Three cheap,\n  phase-invariant detectors (autocorrelation, run-length combs, shift\n  self-similarity) vote first. When they agree, that is the answer. They fail on\n  *different* images, so agreement is strong evidence.\n- **Principled arbitration when they disagree.** A fused evidence stack\n  (spectral, tile-Rayleigh, within-cell variance, and a round-trip\n  \"distillability\" score) resolves the hard cases per axis, with explicit rules\n  for the failure modes that break naive tools: octave\u002Fharmonic traps,\n  content-scale-versus-pixel-scale, and cross-axis disagreement.\n- **Handles what fixed grids can't.** Non-integer cell sizes, sub-pixel drift,\n  warped and non-uniform grids, heavy anti-aliasing, and JPEG block artifacts\n  are all first-class cases, not afterthoughts.\n- **Two-stage reconstruction: crisp structure, accurate color.** Once the grid\n  is known, the downscale decouples *placement* from *color*. A small adaptive\n  color quantization is used **only to decide structure** - each cell votes\n  among clean, flat quantized labels, so region boundaries and outlines come\n  out crisp instead of smeared. Each cell is then colored from the **original,\n  un-quantized pixels** that carry its winning label, so the final colors are\n  accurate and no real color (a rare highlight, a 1px accent) is ever clamped\n  away. This is how it gets snapper-clean lines without snapper's color loss.\n- **Verified and fast.** Every result is checked against a graded ground-truth\n  benchmark. The Rust core is 11-24x faster than the reference at 2.5-4x lower\n  memory, converting a typical image in well under a second.\n\n![A gallery of conversions: koi pond, dragon, raven, lighthouse, frog, and mech, each shown as fake input and true-pixel output](docs\u002Fimages\u002Fexamples.png)\n\nThere is a limit to what pure image processing can recover from a badly damaged\nimage. For the hardest inputs, [the neural version](#the-neural-version) picks\nup where this leaves off.\n\n## Accuracy\n\nMeasured with [pixel-bench](https:\u002F\u002Fgithub.com\u002FRetro-Diffusion\u002Fpixel-bench), an open\nbenchmark that distorts native pixel art through 43 categories of real-world\ndamage (fractional and non-square upscales, blur, JPEG, noise, grid drift,\nAI-upscaler mush, painterly fake-pixel texture, broken outlines, dead pixels,\nand more) and scores how well each tool recovers the original. Across 100 source\nimages and 4,300 distorted inputs:\n\n![Benchmark: how well each tool rebuilds the pixel art, on exact native size, within one pixel, and grid alignment](docs\u002Fimages\u002Fbenchmark-accuracy.png)\n\n| Tool | Exact native size | Within 1 pixel | Grid alignment |\n|---|---|---|---|\n| **Pixel Art Fixer** | **77%** | **84%** | **94%** |\n| PixelDetector | 4% | 7% | 80% |\n| unfake.py | 3% | 8% | 67% |\n| PixelSnapper | 4% | 19% | 63% |\n| Naive baseline | 2% | 4% | 50% |\n\nPixel Art Fixer recovers the exact native resolution on 77% of images, where no\nother tool clears 5%, and its detected grid lines sit on the true grid 94% of\nthe time. When it gets the size right, its colours land within a mean CIELAB\ndifference of about 1.6 (barely perceptible). It leads all 43 distortion\ncategories, from clean integer upscales through heavy mush, painterly fakes,\nbroken outlines, and even the deliberately extreme \"kitchen sink\" that stacks\nevery kind of damage at once. For inputs damaged past what any grid detector can\nrecover, [the neural version](#the-neural-version) takes over.\n\nFull methodology, per-category tables, and reproduction instructions live in the\n[pixel-bench](https:\u002F\u002Fgithub.com\u002FRetro-Diffusion\u002Fpixel-bench) repo.\n\n## Table of contents\n\n- [Accuracy](#accuracy)\n- [Usage](#usage)\n  - [Python](#python)\n  - [Rust](#rust)\n  - [Options and output](#options-and-output)\n- [The neural version](#the-neural-version)\n- [How it works](#how-it-works)\n  - [Pipeline overview](#pipeline-overview)\n  - [Grid detection: the evidence channels](#grid-detection-the-evidence-channels)\n  - [Consensus and arbitration](#consensus-and-arbitration)\n  - [Reconstruction](#reconstruction)\n  - [Why this beats naive methods](#why-this-beats-naive-methods)\n- [Made by Retro Diffusion](#made-by-retro-diffusion)\n- [License](#license)\n\n## Usage\n\nTwo implementations live in this repository. They produce the same answers; pick\nby context.\n\n- **[`python\u002F`](python\u002F)** is the reference: clearest to read, easiest to hack\n  on and extend.\n- **[`rust\u002F`](rust\u002F)** is the native core: one dependency-free binary, 11-24x\n  faster, for servers and batch jobs.\n\n### Python\n\nRequires Python 3.9+ and `numpy`, `scipy`, `opencv-python`, and `Pillow`.\n\n```bash\ncd python\npip install -r requirements.txt\n```\n\nRun the CLI on an image:\n\n```bash\npython -m pixelfixer.cli input.png                    # print detection JSON\npython -m pixelfixer.cli input.png --extract out.png  # write the fixed pixel art\npython -m pixelfixer.cli input.png --overlay grid.png # write a grid overlay\npython -m pixelfixer.cli folder\u002F --json results.json  # batch a folder\n```\n\nOr call it from Python:\n\n```python\nimport numpy as np\nfrom PIL import Image\nfrom pixelfixer import detect\nfrom pixelfixer.reconstruct import reconstruct\n\nrgba = np.array(Image.open(\"input.png\").convert(\"RGBA\"))\nr = detect(rgba)                       # {step_x, step_y, cols, rows, consensus, ...}\nout = reconstruct(rgba, r[\"step_x\"], r[\"step_y\"], r[\"cols\"], r[\"rows\"])\nImage.fromarray(out).save(\"out.png\")   # true pixel art at r[\"cols\"] x r[\"rows\"]\n```\n\nA single-call server entry point takes bytes in and returns PNG bytes out:\n\n```python\nfrom pixelfixer.api import process\n\nresult = process(png_or_jpeg_bytes)               # full quality\nresult = process(png_or_jpeg_bytes, mode=\"fast\")  # bounded latency\n# result: cols, rows, step_x, step_y, consensus, confidence, png (bytes), timings\n```\n\n### Rust\n\nRequires a stable Rust toolchain. No system libraries, no OpenCV, nothing to\ninstall beyond `cargo`.\n\n```bash\ncd rust\ncargo build --release        # -> target\u002Frelease\u002Fpixelfixer\n```\n\n```bash\n# detect + reconstruct, writing the fixed image\n.\u002Ftarget\u002Frelease\u002Fpixelfixer process input.png output.png        # full mode\n.\u002Ftarget\u002Frelease\u002Fpixelfixer process input.png output.png fast   # fast mode\n\n# detection only (no output file), one JSON line per image\n.\u002Ftarget\u002Frelease\u002Fpixelfixer full  input.png\n.\u002Ftarget\u002Frelease\u002Fpixelfixer fast  input.png\n```\n\n`process` prints one JSON line with the detected size, cell steps, decision\npath, and timings:\n\n```json\n{\"file\": \"input.png\", \"cols\": 104, \"rows\": 138, \"step_x\": 10.44,\n \"step_y\": 10.49, \"consensus\": \"fast:ac+rl(S)\", \"mode\": \"full\",\n \"detect_s\": 0.19, \"recon_s\": 0.11, \"peak_rss_mb\": 147.6}\n```\n\n### Options and output\n\n- **Modes.** `full` (default) runs the complete arbitration for best accuracy.\n  `fast` runs only the cheap detectors for bounded latency, flagging low\n  confidence when they disagree.\n- **The output is 1x pixel art.** It is often tiny (for example 64x64). Display\n  it with nearest-neighbor scaling only (`image-rendering: pixelated` in CSS,\n  `imageSmoothingEnabled = false` on a canvas). `cols` and `rows` in the JSON\n  tell you the size without opening the file.\n- **Confidence.** The `consensus` string records the decision path:\n  `fast:...` (the cheap detectors agreed, high confidence), a `+`-joined method\n  list (a supermajority vote), or `arbitrated` (the evidence stack decided).\n- **Input limits.** PNG and JPEG, minimum side 16 px, maximum 4 megapixels.\n  Transparency is preserved as the per-cell majority.\n\n## The neural version\n\nThis open-source tool is the best you can do with classical image processing,\nand it clears the great majority of real inputs. But some images are damaged\npast what any grid detector can recover: extreme jitter with no boundary\nlattice left, cells under about 3 px, or heavy dithering that hides the true\nstep.\n\nFor those, Retro Diffusion hosts a **neural Pixel Art Fixer**, free to use:\n\n### [Try the Pixel Art Fixer on retrodiffusion.ai](https:\u002F\u002Fretrodiffusion.ai\u002Fpixel-art-fixer)\n\nThe neural engine is trained on real pixel art rather than measuring a grid. It\nsolves more edge cases, reconstructs detail and palettes this algorithm has to\napproximate, and restores clean alpha where the classical pipeline can only pool\nwhat is there. It runs right in the browser, no signup required, and is\nexclusive to retrodiffusion.ai. The two share a design goal: real pixels out,\nready for a game.\n\n## How it works\n\n### Pipeline overview\n\nConversion is two decoupled halves:\n\n1. **Grid detection** (`detect`) finds the pseudo-pixel cell size per axis\n   (`step_x`, `step_y`, sub-pixel), the native output resolution\n   (`cols`, `rows`), and a `consensus` string recording how it decided.\n2. **Reconstruction** (`reconstruct`) takes that grid and collapses the source\n   down to the native true-pixel image.\n\nDetection is the hard part, and the whole architecture exists to defeat four\nspecific failure classes: octave\u002Fharmonic ambiguity (a 2x or 1\u002F2 answer that\nscores almost as well as the truth), content scale masquerading as pixel scale,\nmiscounting under grid drift, and the regressions that come from piling up\none-off heuristics.\n\n### Grid detection: the evidence channels\n\nThe core problem is recovering the lattice when every \"pixel\" is a large,\nmushy, warped, or compression-damaged block. Each of the following channels\nmeasures periodicity through an independent physical signal, so they fail on\ndifferent images.\n\n![Detected pseudo-pixel grid overlaid on a fake pixel art raven](docs\u002Fimages\u002Fgrid-detection.png)\n\nThree cheap, phase-invariant detectors run first:\n\n- **Autocorrelation (`autocorr.py`).** The lattice lives in boundary positions\n  *shared across rows*, not in any single scanline. It projects edge and\n  curvature features into row-bands, takes a banded autocorrelation, and scores\n  candidate steps with a comb-minus-anti-comb score (reward periodicity at\n  multiples of the step, penalize it at half-multiples). This is the precision\n  leader, refined to sub-percent step error.\n- **Run-lengths (`runlengths.py`).** Pixel art, even mushy, is made of runs.\n  Distances between color-change boundaries are integer multiples of the cell\n  size; a soft-GCD comb over those distances (with coherence smoothing so real\n  boundaries that persist across scanlines are trusted) finds it. The fastest\n  family, and its comb-peak height is a calibrated confidence.\n- **Self-similarity (`selfsim.py`).** An image re-aligns with itself when\n  shifted by a whole cell, so the shift-dissimilarity curve dips at multiples of\n  the step. A comb t-statistic beats odd-harmonic aliasing, and\n  dispersion-adaptive tile voting handles grids that drift across the image.\n\nWhen the cheap detectors disagree, a heavier evidence stack arbitrates:\n\n- **Fused spectral and tile channels (`fusion.py`, `channels.py`).** An\n  equal-weight sum of the channels that empirically rank the true step best:\n  tile-local Rayleigh phase-coherence on gradient and curvature maps, a Welch\n  spectral score (phase-free, strongest on pure mush), and global Rayleigh\n  coherence.\n- **Within-cell variance contrast (`varcontrast.py`).** A grid is correct when\n  cells are internally uniform. This \"square packer\" scores how much more\n  homogeneous cells are at the best phase than the worst, computed from summed\n  area tables. It carries the signal on images so mushy that no edges survive at\n  all.\n- **Distillability (`reconsearch.py`).** The octave arbiter. It measures what\n  downscaling at each candidate size would destroy, using the identity that a\n  box-downscale then upscale round-trip error equals total within-cell variance.\n  A two-factor score (an anti-phase term plus an octave killer) separates the\n  true fundamental from its harmonics, which is the single biggest failure class\n  for naive detectors.\n\n### Consensus and arbitration\n\nDetection is consensus-first, in layers:\n\n1. **Calibrated early exit.** If autocorrelation and run-lengths agree on the\n   size and the run-length comb height clears a level that was always correct on\n   the benchmark, return immediately (`consensus: \"fast:ac+rl(S)\"`).\n2. **Supermajority.** After a fourth, fused-argmax voter is added, if three or\n   more methods agree on a size with a sane aspect ratio, take it. Two of four\n   is deliberately *not* enough: the methods share some content and texture\n   locks, so a bare majority can be a correlated failure.\n3. **Per-axis arbitration.** With no supermajority, each axis is scored over a\n   candidate pool (every method's step plus autocorrelation's top peaks). The\n   score sums the fused evidence, the variance-contrast weight, an agreement\n   bonus, and the distillability term, with a penalty on steps larger than the\n   detail scale. Among everything scoring near the best, the *smallest*\n   qualifying step wins, the harmonic-hygiene rule all three cheap detectors\n   converged on independently.\n4. **Cross-axis reconciliation.** On wild axis disagreement it prefers the finer\n   step on both axes (a too-fine grid subdivides losslessly; a too-coarse one\n   destroys detail), and near-equal axes snap square.\n\n`fast` mode runs only step 1 and the cheap detectors, for bounded latency.\n\n### Reconstruction — two-stage packing (`two_stage_pack`)\n\nGiven the grid (`cols` x `rows`), reconstruction packs the source down to one\ntrue pixel per cell. The key idea is to **decouple structure from color**, which\nis what gets clean lines *and* accurate colors at the same time:\n\n![Zoomed detail: mushy off-grid input versus one true pixel per cell](docs\u002Fimages\u002Fpixel-detail.png)\n\n1. **Regular even grid.** With the native size known, the true cell boundaries\n   are just an even lattice (`x * cols \u002F w`). No per-cut snapping: snapping to\n   local gradients chases *content* edges on detailed art and produces sliver \u002F\n   double-wide cells, so it is dropped entirely.\n2. **Adaptive quantization (structure only).** The image is k-means quantized to\n   an adaptive number of colors `K` (`adaptive_k`: coarse color-complexity of\n   the image, clamped to `[16, 48]`). This palette is used *only* to decide\n   placement, never for output.\n3. **Stage 1 - placement.** Each cell takes a center-weighted vote over the\n   clean quantized **labels**. Because the vote is between flat, unambiguous\n   colors (not the blurred ramp values in the raw image), region boundaries and\n   outlines land crisp instead of smeared. This is the mechanism behind\n   pixel-snapper's clean lines.\n4. **Stage 2 - color.** Each cell is colored from a center-weighted mean of the\n   **original, un-quantized pixels that carry its winning label**. The color is\n   therefore accurate and denoised from the real image, and rare colors survive\n   - a boundary cell picks \"outline\" cleanly, then gets the *true* outline color\n   rather than a blend or a palette-clamped approximation.\n\nThe legacy grid-cut reconstructor (`reconstruct`, phase solve + snapped cuts +\nwarp refinement + mode pooling) is kept as an opt-out (`two_stage=False` \u002F\n`legacy`) but is no longer the default.\n\n### Why this beats naive methods\n\n- A naive \"strongest period\" locks onto content, not pixels. This uses the\n  *finest consistent* period and caps the step at the detail scale, so a 60 px\n  cell cannot coexist with 3 px detail.\n- A fixed integer grid assumes one global cell at phase 0. This handles\n  non-integer cells, sub-pixel drift (per-window counting), and warped grids\n  (per-band cuts).\n- Octave traps, where 2x and 1\u002F2 score nearly as well as the truth, are broken\n  structurally by the distillability arbiter rather than by fragile thresholds.\n- Smooth resampling erases first-difference edges; the signal moves into the\n  second derivative, which the curvature feature maps track.\n- JPEG's 8 px block lattice is detected and notched out before the channels see\n  it, so compression is not mistaken for the art grid.\n\nFull technical documentation, including every channel, rule, and the reasoning\nbehind them, is in [`docs\u002FHOW_IT_WORKS.md`](docs\u002FHOW_IT_WORKS.md).\n\n## Made by Retro Diffusion\n\n![Retro Diffusion: generate real pixel art from the start](docs\u002Fimages\u002Fmade-by-rd.png)\n\nConverting fake pixel art is a repair job. The better move is to never make fake\npixel art in the first place.\n\n[Retro Diffusion](https:\u002F\u002Fretrodiffusion.ai) generates real, grid-aligned,\npalette-controlled pixel art from the start: characters, tilesets, animations,\nand game-ready sprites, built and trained by working pixel artists and designed\nfor game developers. No conversion step, because the pixels are real when they\ncome out. New accounts get free credits, there is no subscription, and credits\nnever expire.\n\n**[Generate real pixel art at retrodiffusion.ai](https:\u002F\u002Fretrodiffusion.ai)**\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","Pixel Art Fixer 是一个专用于将伪像素画（如AI生成或上采样失真图像）还原为真实网格对齐像素画的图像处理工具。它不依赖深度学习模型，而是通过多路独立检测器（自相关、游程分析、位移一致性）达成共识，自动恢复隐含像素网格，精准重采样为整数尺寸、无抗锯齿、单色像素的原生分辨率图像。支持处理偏移网格、非整数像素尺寸、模糊边缘及JPEG压缩损伤等典型问题，输出可直接用于游戏开发、动画帧编辑、调色板替换与图块拼接。适用于像素艺术家、游戏开发者及复古风格内容创作者对AI生成图像进行专业级修复。",2,"2026-07-16 02:30:09","CREATED_QUERY"]