# VGMdb Folder Image Creator

> **Status:** Active
> **Category:** Data Extraction
> **Language:** Python 3
> **Script file:** `folder-jpg-creator-v3.py`

## Purpose

Generates `folder.jpg` thumbnail files for album folders so that Windows Explorer and media players can display album art as the folder icon. For each album subfolder that contains a `Scans/` directory, the script selects the best available scan image, resizes it if necessary, and saves it as `folder.jpg`.

## Requirements

### Dependencies

```bash
pip install Pillow
```

| Package | Purpose |
|---------|---------|
| `Pillow` | Image opening, mode conversion, thumbnail resizing, and JPEG saving |

## Input

The script operates on a root directory containing album subfolders. Each album folder is expected to have a `Scans/` subdirectory containing image files.

| Item | Description | Example |
|------|-------------|---------|
| Root directory | Directory containing album subfolders | Passed as a command-line argument, or defaults to the script's own directory |
| `Scans/` subdirectory | Inside each album folder; contains scan images | `Front.jpg`, `Disc.png`, `Insert Front.jpg` |

## Output

| Item | Description |
|------|-------------|
| `folder.jpg` | Created inside each album folder that has a usable scan image |
| `missing_folder_jpg.txt` | Text report listing all album folders where no source image was found; only written if there are missing entries |

## Usage

```bash
# Use the script's own directory as the root
python folder-jpg-creator-v3.py

# Specify a root directory explicitly
python folder-jpg-creator-v3.py "/path/to/music/collection"
```

After processing, press Enter at the prompt to close the console window.

## Image Selection Priority

When multiple images are present in a `Scans/` folder, the script selects the highest-priority match from this ordered list:

| Priority | File patterns matched |
|----------|-----------------------|
| 1 (highest) | `Front.jpg`, `Front.png`, `Booklet Front.jpg`, `Booklet Front.png` |
| 2 | `Front.*` (any extension starting with "Front") |
| 3 | `Insert Front.jpg`, `Insert Front.png` |
| 4 | `Slipcase Front.jpg`, `Slipcase Front.png` |
| 5 | `Disc.jpg`, `Disc.png`, `Discs.jpg`, `Discs.png` |
| 6 | `Disc.*` (any extension starting with "Disc") |
| 7 (lowest) | `Case Front.jpg`, `Case Front.png` |

If no pattern matches, the folder is counted as missing and logged to `missing_folder_jpg.txt`.

## Resize Behaviour

| Condition | Action |
|-----------|--------|
| `folder.jpg` already exists and is under 2 MB | Skipped — no changes made |
| `folder.jpg` already exists but exceeds 2 MB | Resized in-place |
| `folder.jpg` does not exist, source image found | Copied and resized to `folder.jpg` |
| `folder.jpg` does not exist, no source image | Logged as missing |

All images are saved as JPEG at **quality 90** and resized to fit within **1000×1000 px** (aspect ratio preserved using `thumbnail()`). RGBA and palette-mode images are converted to RGB before saving.

## Console Output

The script prints coloured progress lines for each folder processed, followed by a summary table:

```
  ✔  OK                           Album Title A
  ✚  Creating                     Album Title B   ← Front.jpg
  ⟳  Resizing                     Album Title C   (3.2 MB → ≤2 MB)
  ✘  No source found              Album Title D
```

Summary counts created, resized, skipped, and missing folders.

## Examples

```bash
# Run against the current directory
python folder-jpg-creator-v3.py

# Run against a specific music library path
python folder-jpg-creator-v3.py "E:\Music\Game Soundtracks"

# Typical summary output:
# ══════════════════════════════════════════════════════════════
#   SUMMARY
#   ──────────────────────────────────────────────────────────
#   ✔  Created      87   folder.jpg files
#   ⟳  Resized       3   oversized folder.jpg files
#   –  Skipped     412   (already OK)
#   ✘  Missing      14   no source image found
#   ──────────────────────────────────────────────────────────
#   Log saved → /path/to/missing_folder_jpg.txt
# ══════════════════════════════════════════════════════════════
```

## Notes

- The script treats any top-level subfolder of the root directory as an album folder, **except** folders named `scans` (case-insensitive), which are skipped.
- The `Scans/` subdirectory name match is case-insensitive — `scans`, `Scans`, and `SCANS` all work.
- When the script's own directory is used as the root (default), the `BASE_DIRECTORY` constant is set to `os.path.dirname(os.path.abspath(__file__))`. Running the script from a different working directory will still use the script's location.
- ANSI colour output is enabled automatically on Windows 10+ via a `SetConsoleMode` call. On Linux/macOS, ANSI codes work natively.
- The size check is based on file size in bytes (> 2 MB), not on pixel dimensions. An existing `folder.jpg` is only resized if it exceeds the 2 MB file size threshold — pixel dimensions of existing files are not checked.
- `missing_folder_jpg.txt` is overwritten on each run if there are missing entries. If all folders are covered, the file is not created or updated.

## Related Scripts

- [VGMdb HTML Data Extractors](extract.md) — extracts catalogue numbers and URLs from VGMdb pages; can identify which albums to target
