PIXATTO is a desktop texture tool for turning images, videos, and 3D model textures into pseudo-pixel art. It runs on Windows, Linux, and macOS, and is written in C++20 with SDL3, OpenGL, and Dear ImGui.
| Image workflow | Video workflow | 3D model texture workflow |
|---|---|---|
![]() |
![]() |
![]() |
PIXATTO keeps the editing loop simple: import an asset, tune the pixelization, palette, dithering, and adjustment controls, preview the result live, then export the processed output. Reusable presets and batch image processing are available when the same look needs to be applied again.
It supports standalone images, videos, and model texture workflows:
- Images: PNG, JPG/JPEG, BMP, TGA, GIF, WebP, JPEG XL, QOI, TIFF, and PNM/PPM/PGM/PBM.
- Videos: MP4, MOV, MKV, WebM, AVI, M4V, MPG/MPEG, and OGV through an external FFmpeg/ffprobe installation.
- 3D models: GLB, glTF, OBJ, FBX, and DAE.
- Palettes: Lospec
.hexfiles, bundled default palettes, and custom palettes made in the app.
Image imports use PIXATTO's standard image workflow. The app shows a result viewport by default, with optional two-view layouts for comparing the original and processed image. Imports decode to a single flattened image; animated imports are treated as still images for now, and imported alpha is simplified to binary transparency.
Features include:
- Block pixelization with linear-light averaging.
- Palette mapping or per-channel color reduction.
- Ordered dithering, blue-noise dithering, error diffusion, Riemersma dithering, clustered-dot patterns, and directional patterns.
- Brightness, contrast, gamma, levels, saturation, and tint controls.
- Saved processing presets for reusing common looks.
- Batch pixelizing for multiple images, with PNG or raw indexed output.
- Undo and redo for processing edits.
- Independent zoom for original and result previews.
- Direct numeric entry by double-clicking numeric controls.
Video imports switch PIXATTO into video mode. The app shows one converted viewport with a timeline, play/pause control, scrubber, timecode, frame counter, and export progress.
Video mode uses external ffmpeg and ffprobe:
- On Windows, PIXATTO looks next to
pixatto.exefirst, then onPATH. - On Linux and macOS, PIXATTO looks on
PATH. - PIXATTO does not bundle FFmpeg binaries.
Scrubbed and paused frames are decoded, processed with the current settings, collapsed to one output pixel per pixelization block, and uploaded as the preview texture. Export streams decoded frames through PIXATTO and into an FFmpeg encoder. Compatible export settings can use GPU Processing for the shader-backed fast path, with CPU fallback for generated palettes, error diffusion, and Riemersma dithering.
On Windows, timeline playback uses Media Foundation for native preview decoding instead of launching FFmpeg for every displayed frame. Linux and macOS native playback backends are planned; until then, unsupported preview decode falls back to still-frame updates.
Available export choices depend on the detected FFmpeg build. Video codec, audio handling, and container are selected separately:
- Video codecs: H.264, H.265, AV1, VP9, and detected NVIDIA NVENC, AMD AMF, or Intel QSV variants.
- Audio: copy compatible source audio, encode AAC, encode Vorbis, or omit audio.
- Containers: MP4 for H.264/H.265/AV1, WebM for VP9, and MKV for any supported combination.
Hardware encoders expose speed presets and QP quality controls, with lower QP values targeting higher visual quality.
Model imports switch PIXATTO into model mode. GLB, glTF, OBJ, FBX, and DAE files are loaded into an unshaded OpenGL preview so the processed textures can be checked directly on the mesh.
In model mode:
- The left sidebar shows a material list and a texture drawer.
- Models with no assigned textures render with a flat grey material.
- Imported images are added to the texture drawer instead of replacing the model.
- Textures can be dragged from the drawer onto materials.
- The same pixelization, palette, adjustment, and dithering controls apply to every assigned diffuse/base-color texture together.
- The original viewport shows a gallery of source textures.
- The working viewport shows the processed model preview.
PIXATTO currently processes diffuse/base-color textures only. Normal, metallic, roughness, occlusion, and other data maps are left untouched.
The in-app help button next to the language selector lists the active controls. The main shortcuts are:
Ctrl+Z: undo.Ctrl+Shift+Z: redo.Ctrl+mouse wheelover an image viewport: zoom the image.- Left drag over the model preview: orbit.
- Middle drag, right drag, or
Shift+left dragover the model preview: pan. - Mouse wheel over the model preview: zoom.
Reset view: fit the camera around the model.Origin: center the model preview around world0,0,0.
Export... > Export PNG adapts to the current workflow:
- In image mode, it exports the processed image.
- In model mode, it exports the processed model textures only, prompting once per affected texture.
PNG export writes indexed 8-bit PNGs when the result fits in 256 palette entries, and truecolor PNGs otherwise.
Exported image dimensions use one output pixel per pixelization block, so a source image becomes ceil(width / Pixel Size) by ceil(height / Pixel Size).
Export... > Export Raw is available for images. It writes an 8-bit indexed .raw file, a shared .pal palette sidecar, and an optional .msk transparency mask.
Export... > Export Video is available in video mode. It writes constant-frame-rate output using the probed average FPS, and combinations that require even dimensions pad odd processed output sizes before encoding.
Download the latest release from the Releases page.
PIXATTO uses CMake presets and fetches its libraries at configure time.
cmake --preset ninja-release
cmake --build --preset ninja-release
.\build\ninja-release\pixatto.exeInstall SDL build dependencies first. On Ubuntu:
sudo apt-get install build-essential cmake git ninja-build pkg-config \
libdbus-1-dev libdecor-0-dev libegl1-mesa-dev \
libgl1-mesa-dev libgles2-mesa-dev libibus-1.0-dev \
libwayland-dev libx11-dev libxcursor-dev \
libxext-dev libxfixes-dev libxi-dev libxkbcommon-dev libxrandr-dev \
libxss-dev wayland-protocols
cmake --preset ninja-release
cmake --build --preset ninja-release
./build/ninja-release/pixattobrew install cmake ninja
cmake --preset ninja-release
cmake --build --preset ninja-release
./build/ninja-release/pixattoRaw export writes a headerless 8-bit indexed image plus sidecar files. Its width and height are the exported pixel-block dimensions from the current Pixel Size setting.
<image>.rawcontains exactlywidth * heightbytes in row-major order, left-to-right and top-to-bottom. Each byte is a palette index from0to255.<palette>.palcontains the shared palette. If a saved palette is active, the sidecar is named from that palette, so multiple raw images can share one palette file. If there is no saved active palette, it uses the exported image stem. The file is ASCII text with one uppercaseRRGGBBcolor per line; the line number is the palette index.<image>.mskis written only when the result contains transparent pixels. It containsceil(width * height / 8)bytes in the same pixel order. Bits are packed most-significant-bit first within each byte. A1bit means transparent; a0bit means opaque. For transparent pixels, the corresponding.rawindex byte is0and should be ignored.
PIXATTO raw export supports up to 256 opaque palette colors plus binary transparency. It does not store width or height in the files, so projects should keep dimensions in their own asset metadata.
For pixel i = y * width + x:
uint8_t index = raw[i];
bool transparent = mask && (mask[i / 8] & (0x80 >> (i & 7)));The build statically links SDL3 release-3.4.4, SDL_image release-3.4.2, Dear ImGui v1.92.7, stb image libraries, tinygltf v2.9.7, tinyobjloader v2.0.0rc13, ufbx v0.21.3, and tinyxml2 11.0.0. Video import/export uses external FFmpeg and ffprobe executables; they are not redistributed with PIXATTO. See THIRD_PARTY.md for license notes.
PIXATTO is released under the MIT License.


