A complete TIM2 (.tm2) texture toolkit for the PlayStation 2. Convert standard images into PS2-native TIM2 textures, extract existing TIM2 files back into regular images, inspect their internal structure, and verify their integrity — all from a single command-line script.
Built for PS2 homebrew development, game modding, and texture pipeline work, with accurate handling of GS pixel formats, CLUT palettes, VRAM swizzling, and mipmap chains.
- Image → TIM2 conversion in four PS2 GS pixel formats: 32-bit, 16-bit, 8-bit indexed, and 4-bit indexed
- TIM2 → Image extraction, converting
.tm2files back into common image formats - CLUT (palette) generation for indexed formats, including proper 8-bit CLUT swizzling
- GS VRAM swizzle support for 32-bit and 16-bit formats
- Mipmap chain generation for all formats — 32-bit, 16-bit, 8-bit indexed, and 4-bit indexed
- Alpha premultiplication, matching PS2 GS rendering behavior
- Floyd–Steinberg dithering for 4-bit and 8-bit indexed output
- Power-of-2 dimension handling, with optional automatic resize up or down
- Batch conversion from wildcards or a text list file
.tm2file inspection (--info) showing header, format, CLUT, and GS Tex0 data.tm2integrity verification (--verify) with a 12-point structural check
- Python 3
- Pillow (
PIL)
Install Pillow with:
pip install Pillow
.png .jpg .jpeg .bmp .tga .tiff .tif .webp .gif .ppm .pgm .pbm .ico .dds
.png .jpg .jpeg .bmp .tga .tiff .tif .webp .ppm
| Format | Description |
|---|---|
32bit |
RGBA8888 — full color + 8-bit alpha — best for textures |
16bit |
RGBA5551 — 32K colors + 1-bit alpha — smaller file size |
8bit |
Indexed8 — 256 colors + CLUT — characters, environments |
4bit |
Indexed4 — 16 colors + CLUT — icons, UI elements |
python3 ps2_tim2_tool.py (filename) --format 32bit
python3 ps2_tim2_tool.py (filename) --format 16bit
python3 ps2_tim2_tool.py (filename) --format 8bit
python3 ps2_tim2_tool.py (filename) --format 4bit
python3 ps2_tim2_tool.py (filename) (filename) (filename) --format 32bit
python3 ps2_tim2_tool.py (filename) --format 8bit --dither
python3 ps2_tim2_tool.py (filename) --format 32bit --no-premult
python3 ps2_tim2_tool.py (filename) --format 32bit --output (filename)
python3 ps2_tim2_tool.py (filename) --format 32bit --output-dir (directory)
python3 ps2_tim2_tool.py (filename) --format 32bit --resize up
python3 ps2_tim2_tool.py (filename) --format 32bit --resize down
python3 ps2_tim2_tool.py (filename) --format 32bit --swizzle
python3 ps2_tim2_tool.py (filename) --format 32bit --mipmaps
python3 ps2_tim2_tool.py (filename) --format 32bit --swizzle --mipmaps --resize up
python3 ps2_tim2_tool.py --list (filename)
python3 ps2_tim2_tool.py (filename) --info
python3 ps2_tim2_tool.py (filename) --verify
python3 ps2_tim2_tool.py (filename) --extract png
python3 ps2_tim2_tool.py (filename) --extract jpg
python3 ps2_tim2_tool.py (filename) --extract bmp
python3 ps2_tim2_tool.py (filename) --extract tga
python3 ps2_tim2_tool.py (filename) --extract tiff
python3 ps2_tim2_tool.py (filename) --extract webp
python3 ps2_tim2_tool.py (filename) --extract ppm
python3 ps2_tim2_tool.py --list-formats
| Option | Description |
|---|---|
--format, -f |
Output format: 4bit | 8bit | 16bit | 32bit |
--output, -o |
Output file path (single file only) |
--output-dir |
Output directory for all converted files |
--no-premult |
Disable alpha premultiplication |
--dither |
Enable Floyd–Steinberg dithering (4-bit and 8-bit) |
--resize up | down |
Resize non-power-of-2 images up or down to the nearest power of 2 |
--swizzle |
Apply GS VRAM swizzle to pixel data (32-bit and 16-bit only) |
--mipmaps |
Generate a full mipmap chain stored in the TIM2 file (all formats) |
--info |
Read and display info from an existing .tm2 file |
--verify |
Verify the integrity of a .tm2 file (12 checks) |
--list |
Convert images listed in a text file (filename + format per line) |
--extract |
Extract TIM2 to an image format |
--list-formats, -l |
List available formats and options |
When using --list, provide a plain text file with one entry per line, containing the filename and target format:
(filename) 32bit
(filename) 16bit
(filename) 8bit
- Non-power-of-2 images are still converted by default, with a warning. Use
--resize upor--resize downto force power-of-2 dimensions. - The
--swizzleoption applies only to32bitand16bitformats. - The
--mipmapsoption applies to all four formats (32bit,16bit,8bit,4bit). - The
--ditheroption applies only to4bitand8bitformats. - When extracting a TIM2 file to a format without alpha support (
.jpg,.bmp,.ppm), transparency is composited onto a white background.
This project is licensed under the MIT License — see the LICENSE file for details.
