macOS · Commodore 64 · bitmap mode

image64

A native macOS app and command-line tool — one shared engine — that converts modern images into pictures a Commodore 64 can display: crop, dither to the 16-color palette, satisfy the per-cell color limits, and export files that load on real hardware.

status: v1.0.0 — engine, app, and CLI are built and tested. Download it from GitHub Releases.

WHAT THE CONVERSION DOES

The same sunset scene converted to C64 multicolor mode: dithered purple and brown sky, dark blue mountains, a light-green sun core A smooth synthetic sunset: violet-to-orange gradient sky, a sun on the horizon, dark mountain silhouettes reflected in water SOURCE C64 MULTICOLOR
Drag the divider. A synthetic test scene (left) and the same scene through the multicolor pipeline (right): resized to 160×200, Floyd‑Steinberg‑dithered to the Colodore palette, then reduced to one shared background plus three colors per 4×8 cell. This pair was generated by a prototype of the app's conversion pipeline; the app itself is not built yet.

THE CONSTRAINTS

The C64's VIC-II chip has a fixed 16-color palette and two bitmap modes. Neither can put arbitrary colors at arbitrary pixels — color choices are made per character cell, and that restriction is what gives C64 images their look. image64 targets both modes:

HiresMulticolor
resolution320 × 200160 × 200, pixels displayed double-wide
cell size8 × 8 px4 × 8 px
colors per cellany 2 of 161 shared background + any 3 of 16
memory8000 B bitmap + 1000 B screen RAM+ 1000 B color RAM + 1 background byte

Both modes display at 8:5, so the crop tool is locked to that aspect regardless of mode.

SIXTEEN COLORS

Every color the VIC-II can produce. Exported files store 4-bit indices; RGB values only matter for color matching and preview, where image64 uses the Colodore reproduction (shown here) or the darker Pepto measurement, selectable.

0 black#000000
1 white#ffffff
2 red#813338
3 cyan#75cec8
4 purple#8e3c97
5 green#56ac4d
6 blue#2e2c9b
7 yellow#edf171
8 orange#8e5029
9 brown#553800
10 light red#c46c71
11 dark grey#4a4a4a
12 grey#7b7b7b
13 light green#a9ff9f
14 light blue#706deb
15 light grey#b2b2b2

HOW IT WORKS

In the app: drop an image, adjust the 8:5 crop on the source, and watch the converted result beside it — every change re-runs the pipeline:

  1. Resize the cropped image to 320×200 or 160×200 (Lanczos).
  2. Adjust brightness, contrast, saturation.
  3. Dither to the 16-color palette — Floyd–Steinberg, ordered (Bayer 4×4), or none.
  4. Enforce cell limits — keep each cell's most frequent colors, remap the rest to the nearest kept color; in multicolor, first pick the one background shared by every cell.
  5. Pack the result into C64 bitmap, screen-RAM, and color-RAM bytes.

The preview is rendered from the packed bytes — not from an intermediate — so the picture on screen is the picture that exports.

The same five steps run from the command line — the CLI and the app call the identical engine code, so a scripted conversion and an app export with the same parameters produce byte-identical files:

image64 convert photo.jpg -o picture.koa   # multicolor, inferred from .koa
image64 convert photo.jpg -o picture.art   # hires, inferred from .art
image64 convert photo.jpg -o out.koa --dither bayer --palette colodore --json

Outputs overwrite without prompting, so a shell for loop batch-converts a directory. For AI agents the repository ships a skill (skills/c64-image-conversion) documenting the CLI surface and the emulator verification loop — and a test keeps that document in sync with --help, so it cannot drift.

WHAT IT EXPORTS

KOALA .koa — multicolor

load address $6000 (2 B)
bitmap (8000 B)
screen RAM (1000 B)
color RAM (1000 B)
background (1 B) — 10003 bytes total

ART STUDIO .art — hires

load address $2000 (2 B)
bitmap (8000 B)
screen RAM (1000 B)
padding (7 B) — 9009 bytes total

Plus a runnable .prg — a self-displaying program that shows the picture anywhere a C64 runs, in VICE or on real hardware — while the .koa and .art files are the standard interchange layouts that existing C64 paint programs and viewers read. With the neighboring Project 64 toolset:

c64 session start
c64 run picture.prg    # display it on the emulated machine