Skip to content

Commit 74cf94b

Browse files
committed
rel 2024.2
1 parent c7fd5df commit 74cf94b

File tree

12 files changed

+213
-43
lines changed

12 files changed

+213
-43
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
All major and minor version changes will be documented in this file. Details of
44
patch-level version changes can be found in [commit messages](../../commits/master).
55

6+
## 2024.2 - 2024/09/15
7+
8+
- support means of image preprocessing through a `resize_method` option. It can take one of the following values:
9+
- **"outerCrop"**: Resizes the image to fit within the target dimensions while preserving its original aspect ratio. Any space left over is filled with black bars (letterboxing), if applicable.
10+
- **"innerCrop"**: Resizes the image by cropping parts of it to fit the target dimensions
11+
- **"stretch"**: Stretches the image to fit the target dimensions exactly, ignoring the original aspect ratio, which can lead to distortion.
12+
- **null**: No resizing method is applied.
13+
614
## 2024.1.1 - 2024/09/13
715

816
- compress images

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ configuration file.
2323
usage: nxtheme-creator [-h] [--nxtheme NXTHEME] [--input INPUT] [--output OUTPUT] [--config CONFIG]
2424
```
2525

26-
2726
**Options**:
2827

2928
- `-h, --help`: Show help message and exit.

documentation/reference/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ A full list of `Nxtheme-creator` project modules.
1010
- [Nxtheme](nxtheme_creator/backends/nxtheme.md#nxtheme)
1111
- [Sarc Tool](nxtheme_creator/backends/sarc_tool.md#sarc-tool)
1212
- [Img Info](nxtheme_creator/img_info.md#img-info)
13+
- [Process Image](nxtheme_creator/process_image.md#process-image)
1314
- [Process Themes](nxtheme_creator/process_themes.md#process-themes)

documentation/reference/nxtheme_creator/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ def cli() -> None: ...
2727
- [Module](./module.md)
2828
- [Backends](backends/index.md)
2929
- [Img Info](./img_info.md)
30+
- [Process Image](./process_image.md)
3031
- [Process Themes](./process_themes.md)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Process Image
2+
3+
[Nxtheme-creator Index](../README.md#nxtheme-creator-index) / [Nxtheme Creator](./index.md#nxtheme-creator) / Process Image
4+
5+
> Auto-generated documentation for [nxtheme_creator.process_image](../../../nxtheme_creator/process_image.py) module.
6+
7+
- [Process Image](#process-image)
8+
- [resize_center_crop](#resize_center_crop)
9+
- [resize_image](#resize_image)
10+
- [resize_outer_crop_letterbox](#resize_outer_crop_letterbox)
11+
- [resize_stretch](#resize_stretch)
12+
13+
## resize_center_crop
14+
15+
[Show source in process_image.py:9](../../../nxtheme_creator/process_image.py#L9)
16+
17+
Resize the image using center crop method.
18+
19+
#### Signature
20+
21+
```python
22+
def resize_center_crop(image: Image.Image): ...
23+
```
24+
25+
26+
27+
## resize_image
28+
29+
[Show source in process_image.py:35](../../../nxtheme_creator/process_image.py#L35)
30+
31+
Resize the image using the specified method and save the output.
32+
33+
#### Signature
34+
35+
```python
36+
def resize_image(input_path, output_path, method="stretch"): ...
37+
```
38+
39+
40+
41+
## resize_outer_crop_letterbox
42+
43+
[Show source in process_image.py:28](../../../nxtheme_creator/process_image.py#L28)
44+
45+
Resize the image using outer crop (letterbox) method.
46+
47+
#### Signature
48+
49+
```python
50+
def resize_outer_crop_letterbox(image: Image.Image): ...
51+
```
52+
53+
54+
55+
## resize_stretch
56+
57+
[Show source in process_image.py:5](../../../nxtheme_creator/process_image.py#L5)
58+
59+
Resize the image by stretching it to the target SIZE.
60+
61+
#### Signature
62+
63+
```python
64+
def resize_stretch(image: Image.Image): ...
65+
```

documentation/reference/nxtheme_creator/process_themes.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
## processImages
1313

14-
[Show source in process_themes.py:123](../../../nxtheme_creator/process_themes.py#L123)
14+
[Show source in process_themes.py:131](../../../nxtheme_creator/process_themes.py#L131)
1515

1616
Process images from the specified input directory to generate Nintendo Switch themes. This
1717
function handles the following tasks:
@@ -44,7 +44,7 @@ def processImages(
4444

4545
## resolveConf
4646

47-
[Show source in process_themes.py:85](../../../nxtheme_creator/process_themes.py#L85)
47+
[Show source in process_themes.py:93](../../../nxtheme_creator/process_themes.py#L93)
4848

4949
Resolve the file paths for layout configurations specified in the `conf` dictionary.
5050
This function checks if the specified layout files exist. If they do not, it attempts
@@ -73,7 +73,7 @@ def resolveConf(nxthemebin: str | None, conf: dict) -> dict: ...
7373

7474
## walkfiletree
7575

76-
[Show source in process_themes.py:16](../../../nxtheme_creator/process_themes.py#L16)
76+
[Show source in process_themes.py:18](../../../nxtheme_creator/process_themes.py#L18)
7777

7878
Create a theme_image_map from an input directory by walking the dir and getting
7979
theme names and corresponding images for each component.

documentation/tutorials/README.md

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

22
# **Tutorial: Generating Nintendo Switch Themes with `nxtheme-creator`**
33

4-
This tutorial will guide you through using the `nxtheme-creator` tool to generate custom themes for your Nintendo Switch. Follow these steps to create multiple themes from images (with optional configuration for layouts)
4+
This tutorial will guide you through using the `nxtheme-creator` tool to generate custom themes for
5+
your Nintendo Switch. Follow these steps to create multiple themes from images (with optional
6+
configuration for layouts)
57

68
## **Step 1: Install `nxtheme-creator`**
79

@@ -13,7 +15,8 @@ python3 -m pip install
1315

1416
## **Step 2: Prepare Your Images**
1517

16-
**Create an Input Directory**: Organize your images in a directory. The directory structure should look like this:
18+
**Create an Input Directory**: Organize your images in a directory. The directory structure should
19+
look like this:
1720

1821
```sh
1922
themes_directory/
@@ -28,20 +31,17 @@ themes_directory/
2831
│ ├── home,lock.jpg
2932
│ ├── apps,set,user.jpg
3033
│ └── news.jpg
31-
└── theme3/
32-
├── home.jpg
33-
├── lock.jpg
34-
├── apps.jpg
35-
├── set.jpg
36-
├── user.jpg
37-
└── news.jpg
34+
└── theme3.jpg
35+
3836
```
3937

40-
Each image file should correspond to a different part of the theme (home screen, lock screen, etc.). But note these may be combined with a comma as shown above to apply one image to multiple parts of the UI
38+
Each image file should correspond to a different part of the theme (home screen, lock screen, etc.).
39+
These may be combined with a comma as shown above to apply one image to multiple parts of the UI.
40+
Alternatively one image e.g. `theme3.jpg` may be used to create all parts of a theme.
4141

4242
## **Step 3: \[Optional] Configure the `conf.json` File**
4343

44-
Create or modify a `conf.json` file in the root directory of `nxtheme-creator`. This file will specify how the tool should process your images. Here’s an example configuration:
44+
Create a `conf.json` file in the root directory of `nxtheme-creator`. This file will specify how the tool should process your images. Here’s an example configuration:
4545

4646
```json
4747
{
@@ -51,16 +51,37 @@ Create or modify a `conf.json` file in the root directory of `nxtheme-creator`.
5151
"set": null,
5252
"user": null,
5353
"news": null,
54-
"author_name": "JohnDoe"
54+
"author_name": "JohnDoe",
55+
"resize_method": "outerCrop"
5556
}
56-
5757
```
5858

59-
Note that items ["home", "lock", "apps", "set", "user", "news"] are configured with the layout file, `.json` may be omitted from the file end, also note that if the file does not exist locally, we fallback to the copy included with `SwitchThemes.exe` if available. If not found, an error is returned
59+
| Key | Value | Descriptionscreen |
60+
| ------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
61+
| home | "DogeLayoutRounded" | \[optional] Path to the layout.json for the home screen or a preset layout, e.g. the "DogeLayoutRounded" provided by nxtheme-creator |
62+
| lock | null | \[optional] Path to the layout.json for the lock screen |
63+
| apps | null | \[optional] Path to the layout.json for the apps screen |
64+
| set | null | \[optional] Path to the layout.json for the settings screen |
65+
| user | null | \[optional] Path to the layout.json for the user section |
66+
| news | null | \[optional] Path to the layout.json for the news section |
67+
| author_name | "JohnDoe" | Name of the author |
68+
| resize_method | "outerCrop" | \[optional] The method used for image resizing. One of \["outerCrop", "innerCrop", "stretch", null] |
69+
70+
Note that items ["home", "lock", "apps", "set", "user", "news"] are configured with a layout file,
71+
`.json` may be omitted from the file end. Also note that if the path does not exist, we use to the
72+
copy included with either the `SwitchThemes.exe`, or the `nxtheme-creator` backend if available.
73+
If not found, an error is returned
74+
75+
The `resize_method` option defines how an image is resized. It can take one of the following values:
76+
77+
- **"outerCrop"**: Resizes the image to fit within the target dimensions while preserving its original aspect ratio. Any space left over is filled with black bars (letterboxing), if applicable.
78+
- **"innerCrop"**: Resizes the image by cropping parts of it to fit the target dimensions
79+
- **"stretch"**: Stretches the image to fit the target dimensions exactly, ignoring the original aspect ratio, which can lead to distortion.
80+
- **null**: No resizing method is applied.
6081

6182
## **Step 4: Run the Tool**
6283

63-
### **Using the Command Line**
84+
### **With the SwitchThemes.exe backend**
6485

6586
Open your terminal or command prompt and run the following command to generate your theme:
6687

@@ -75,26 +96,24 @@ Replace:
7596
- `output_directory` with the directory where you want to save the generated theme files.This defaults to `./output/`
7697
- `conf.json` with the path to your configuration file. Note this is optional, though needed if you wish to customise the layouts or set an `author_name`
7798

78-
### **Example Command**
79-
80-
Assuming you have the following setup:
99+
### **With the nxtheme-creator backend**
81100

82-
- `SwitchThemes.exe` located at `/path/to/SwitchThemes.exe`
83-
- Input directory is `./input_images`
84-
- Output directory is `./themes`
85-
- Configuration file is `./conf.json`
86-
87-
Run the command:
101+
Open your terminal or command prompt and run the following command to generate your theme:
88102

89103
```bash
90-
python3 -m nxtheme-creator --nxtheme /path/to/SwitchThemes.exe --input ./input_images --output ./themes --config ./conf.json
104+
python3 -m nxtheme-creator --input input_directory --output output_directory --config conf.json
91105
```
92106

107+
Replace:
108+
109+
- `input_directory` with the path to your images. This defaults to the directory you run `nxtheme-creator` from
110+
- `output_directory` with the directory where you want to save the generated theme files.This defaults to `./output/`
111+
- `conf.json` with the path to your configuration file. Note this is optional, though needed if you wish to customise the layouts or set an `author_name`
112+
93113
## **Step 5: Verify and Install Your Theme**
94114

95115
1. **Check the Output Directory**: After running the command, check the `output_directory` for the generated theme files (`.nxtheme` files).
96-
97-
2. **Install the Theme**: Follow your preferred method to install the generated theme on your Nintendo Switch. Typically, you would use an NXTheme installer or similar tool to apply the theme.
116+
2. **Install the Theme**: Follow your preferred method to install the generated theme on your Nintendo Switch. Typically, you would use an NXTheme installer or similar tool to apply the theme. For example, https://github.com/exelix11/SwitchThemeInjector
98117

99118
## **Troubleshooting**
100119

nxtheme_creator/conf.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"set": null,
66
"user": null,
77
"news": null,
8-
"author_name": "JohnDoe"
8+
"author_name": "JohnDoe",
9+
"resize_method": null
910
}

nxtheme_creator/process_image.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from PIL import Image, ImageOps
2+
3+
SIZE = (1280, 720)
4+
5+
def resize_stretch(image: Image.Image):
6+
"""Resize the image by stretching it to the target SIZE."""
7+
return image.resize(SIZE, Image.Resampling.LANCZOS)
8+
9+
def resize_center_crop(image: Image.Image):
10+
"""Resize the image using center crop method."""
11+
# Find the aspect ratio of the target SIZE and original image
12+
aspect_ratio_target = SIZE[0] / SIZE[1]
13+
aspect_ratio_original = image.width / image.height
14+
15+
if aspect_ratio_original > aspect_ratio_target:
16+
# Image is wider than target, crop horizontally
17+
new_width = int(aspect_ratio_target * image.height)
18+
offset = (image.width - new_width) // 2
19+
cropped_image = image.crop((offset, 0, offset + new_width, image.height))
20+
else:
21+
# Image is taller than target, crop vertically
22+
new_height = int(image.width / aspect_ratio_target)
23+
offset = (image.height - new_height) // 2
24+
cropped_image = image.crop((0, offset, image.width, offset + new_height))
25+
26+
return cropped_image.resize(SIZE, Image.Resampling.LANCZOS)
27+
28+
def resize_outer_crop_letterbox(image: Image.Image):
29+
"""Resize the image using outer crop (letterbox) method."""
30+
# Add padding if necessary (letterbox)
31+
image.thumbnail(SIZE, Image.Resampling.LANCZOS)
32+
letterbox_image = ImageOps.pad(image, SIZE, color=(0, 0, 0))
33+
return letterbox_image
34+
35+
def resize_image(input_path, output_path, method='stretch'):
36+
"""Resize the image using the specified method and save the output."""
37+
image = Image.open(input_path)
38+
39+
if method == 'stretch':
40+
resized_image = resize_stretch(image)
41+
elif method == 'centerCrop':
42+
resized_image = resize_center_crop(image)
43+
elif method == 'outerCrop':
44+
resized_image = resize_outer_crop_letterbox(image)
45+
else:
46+
return input_path
47+
48+
resized_image.save(output_path, progressive=False)
49+
return output_path

0 commit comments

Comments
 (0)