Skip to content

About

A simple image to ascii converter

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Grainrad ASCII Converter

A local-first browser editor for ASCII, dithering, halftone, glitch, and retro visual effects.

Everything runs in the browser — no uploads, no accounts. Drop an image, a video, or a GLB model, pick an effect, and export the result as PNG, JPG, SVG, or plain text.

Grainrad preview

Features

  • 22 effects across ASCII, pixel sorting, dithering, halftone, CMYK, VHS glitch, scanlines, grain, noise, edge detection, and more.
  • Four input sources: still images, video files, webcam capture, and 3D models.
  • 3D model preview: drag a self-contained .glb (or embedded .gltf) into the editor and orbit it with the mouse; the rendered scene flows through the same effect pipeline.
  • Configurable preview: processed view, split (before/after), and raw source comparisons.
  • Effect-aware controls: sliders, palettes, dither algorithms, and sort comparators only appear for the effect you have selected.
  • Theme-aware UI: monochrome, VT320 amber, cassette green, and cold war radar looks.
  • Installable PWA: install offline from any modern browser.
  • Responsive shell: side panels collapse into drawers on narrow viewports.
  • No telemetry. Effect processing stays on your device. The UI font is bundled; no remote font CDN.

Quick start

npm install
npm run dev

Then open the printed URL (usually http://localhost:5173) and drop in an image.

Available scripts

Command What it does
npm run dev Start the Vite development server with hot module reload.
npm run build Type-check with tsc and produce a production build in dist/.
npm run preview Serve the production build locally to verify the PWA output.
npm run lint Lint the source with ESLint and fail on any warnings.
npm run test Run unit tests with Vitest.
npm run check Lint, test, then build — the same gate the CI workflow runs.

Tech stack

  • React 18 + TypeScript with strict mode enabled across the project.
  • Vite 6 for the dev server, bundling, and PWA generation.
  • Tailwind CSS 3 with custom CSS variables for theming.
  • Three.js for the interactive 3D model viewer.
  • vite-plugin-pwa / Workbox for offline support and the installable shell.
  • Vitest for unit tests on pure utilities.

Project layout

.
├── index.html              # HTML entry, OG metadata, manifest links
├── public/                 # Icons, PWA assets, social preview image
├── src/
│   ├── App.tsx             # ThemeProvider + Editor root
│   ├── main.tsx            # React DOM bootstrap + bundled font
│   ├── index.css           # Tailwind layers + terminal design tokens
│   ├── components/         # Editor surface, canvas, sidebar, 3D viewer
│   ├── contexts/           # Theme context + provider
│   ├── hooks/              # Reusable React hooks (theme)
│   ├── types/              # Effect types, presets, palette definitions
│   └── utils/
│       ├── canvasRenderer.ts  # The 2D Canvas2D effect engine
│       ├── exportArt.ts       # Source-sampled text / SVG export
│       ├── sourceType.ts      # File MIME + extension detection
│       └── motion.ts          # prefers-reduced-motion helper
├── tailwind.config.ts
├── postcss.config.js
├── vite.config.ts
├── vitest.config.ts
├── tsconfig*.json
└── eslint.config.js

How effects are rendered

Canvas and ModelViewer both share the CanvasEffectRenderer in src/utils/canvasRenderer.ts. The renderer:

  1. Down-samples the source into a small "sample" canvas (one cell = one pixel).
  2. Computes luma, red/green/blue, and applies brightness / contrast.
  3. Dispatches to a per-effect drawing routine (ASCII, Bayer/Floyd–Steinberg, halftone, CMYK, etc.).
  4. Composites the processed result back onto the output canvas, honoring the fxOpacity, blur, backgroundOpacity, scanline, and noise-overlay toggles.

For 3D models, Three.js renders into a WebGL canvas that the same renderer reads as its input source — so every 2D effect also applies to 3D content.

Export formats

Format Behavior
PNG / JPG Raster snapshot of the processed preview canvas.
Text Plain ASCII sampled from the source (cell grid, charset, brightness/contrast/invert). An all-space result is still a valid download.
SVG Vector character grid sampled from the source (same path as text export). If the source cannot be sampled, falls back to a raster PNG embedded in an SVG wrapper — not a path-trace of the pixel preview.

Effect index

Category Effects
ASCII & text ascii, dithering
Pixel pixel-sorting, pixelate, pixel-grid, mosaic
Matrix matrix-rain, matrix-dots
Halftone halftone (+ CMYK toggle), halftone-cmyk, halftone-dots, crosses
VHS / analog vhs-glitch, scanlines
Edge detect edge-detection, edge-lines, convolution
Other threshold, invert, led, grain, noise

Accessibility notes

  • UI transitions honor prefers-reduced-motion.
  • Continuously animated effects (matrix-rain, vhs-glitch, grain, noise) freeze to a single frame when reduced motion is preferred. Video and webcam still play because they are user-controlled media.
  • Controls use labels, aria-* attributes, and focus-visible styles.
  • Themes persist via localStorage (graceful fallback when storage is locked).

Browser support

Feature Minimum version
Vite/React Any browser released in the last two years
Canvas 2D All modern browsers (primary effect pipeline)
WebGL Chrome 56+, Firefox 51+, Safari 15+, Edge 79+ (3D viewer)

Contributing

Issues and pull requests are welcome at nkcbuilds/ASCIIconverter. Please run npm run check before submitting.

License

MIT — see LICENSE.

About

A simple image to ascii converter

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages