qr-atomize
v1.2.0
Published
Atomize QR codes to their absolute minimum filesize — 1 pixel per module. Decode and re-render any QR code image (PNG, JPEG, GIF, WebP, BMP, TIFF, ICO) at native resolution. Supports QR codes with embedded logos.
Maintainers
Readme
qr-atomize
Atomize any QR code image to its absolute minimum filesize — 1 pixel per module (without resampling fuzziness or subpixel-rendering issues).
Takes an oversized QR code (PNG, JPEG, GIF, WebP, BMP, TIFF, ICO), decodes it, and re-renders it at native resolution where each symbol module is exactly 1 pixel. Output is a 1-bit PNG (or optionally GIF).
QR codes with embedded logos are fully supported — the logo overlay is discarded during atomization (error correction handles the missing modules).
Example
| Input | Output |
|:-----:|:------:|
|
|
|
| 290×290 px input (6.9 KB) | 29×29 px output (197 B) — 97% reduction! |
Install
npm install qr-atomize # as a dependency
npm install -g qr-atomize # globally for CLI useCLI
# npx (no install needed)
npx qr-atomize input.png
# global install
qr-atomize input.png
qr-atomize input.jpg -o tiny.png
qr-atomize input.gif --border 0 --format gif
qr-atomize input.bmpqr-atomize <input> [options]
Options:
-o, --output <file> Output path (default: <input>-atomized.png)
-b, --border <n> Quiet zone in modules (default: 2)
-f, --format <fmt> Output format: png (default) or gif
-x, --invert Invert output polarity (swap black/white)
-h, --help Show helpLibrary
// ESM
import atomizeQr from 'qr-atomize';
const png = await atomizeQr(readFileSync('qrcode.png'));
// CommonJS
const atomizeQr = require('qr-atomize').default;
const png = await atomizeQr(readFileSync('qrcode.png'));API
atomizeQr(input: Buffer | string, opts?: {
border?: number; // quiet zone in modules (default: 2)
format?: 'png' | 'gif' // output format (default: 'png')
invert?: boolean; // swap black/white (default: auto-detect from input)
}): Promise<Buffer>- input — image buffer or file path (PNG, JPEG, GIF, WebP, BMP, TIFF, ICO)
- returns —
Promise<Buffer>containing the atomized image
Note:
atomizeQris async (returns a Promise) because image decoding uses async operations internally.
Sub-module exports
import { decodeInput, reEncode } from 'qr-atomize';
// decodeInput(buf) → Promise<{ width, height, data }> (raw RGBA pixels)
// reEncode(text, opts?) → Uint8Array (encoded QR image)How it works
- Decode the input image to raw RGBA pixels (via
cross-image) - Parse the QR code using finder-pattern detection and error correction
- Re-encode the decoded payload at
scale: 1(1 pixel per module) as a 1-bit PNG
This is not a resizer — it's a decode-and-remint operation. The output is guaranteed pixel-perfect.
Supported input formats
| Format | Extension |
|--------|-----------|
| PNG | .png |
| JPEG | .jpg, .jpeg |
| GIF | .gif |
| WebP | .webp |
| BMP | .bmp |
| TIFF | .tiff, .tif |
| ICO | .ico |
License
MIT
