progress
This commit is contained in:
409
tools/ora_edit_README.md
Normal file
409
tools/ora_edit_README.md
Normal file
@@ -0,0 +1,409 @@
|
||||
# ora_edit.py
|
||||
|
||||
A command-line utility for editing OpenRaster (ORA) files, supporting layer creation, masking, and entity management.
|
||||
|
||||
## Overview
|
||||
|
||||
`ora_edit.py` provides four main subcommands:
|
||||
- `create`: Create a new ORA file from a PNG image
|
||||
- `mask_element`: Add masked layers for specific entities within an ORA file
|
||||
- `inspect`: Display the structure of an ORA file
|
||||
- `extract_png`: Extract a layer from an ORA file as a PNG
|
||||
|
||||
## Usage
|
||||
|
||||
### Creating an ORA File
|
||||
|
||||
Create a new ORA file from a PNG:
|
||||
|
||||
```bash
|
||||
python3 ora_edit.py create input.png [output.ora] [--layer-name NAME]
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Create ORA with default layer name "base"
|
||||
python3 ora_edit.py create scene.png scene.ora
|
||||
|
||||
# Create ORA with custom layer name
|
||||
python3 ora_edit.py create scene.png scene.ora --layer-name "background"
|
||||
|
||||
# Auto-detect output name (creates scene.ora)
|
||||
python3 ora_edit.py create scene.png
|
||||
```
|
||||
|
||||
### Masking Elements
|
||||
|
||||
Add a masked layer for an entity using a black-and-white mask image:
|
||||
|
||||
```bash
|
||||
python3 ora_edit.py mask_element <input> --mask <mask.png> --entity <name> [--layer LAYER] [--output OUTPUT]
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Mask an element using default "base" layer
|
||||
python3 ora_edit.py mask_element scene.ora --mask door_mask.png --entity "door"
|
||||
|
||||
# Specify which layer to copy and mask
|
||||
python3 ora_edit.py mask_element scene.ora --mask window_mask.png --entity "window" --layer "background"
|
||||
|
||||
# Chain: Convert PNG to ORA, then add masked element
|
||||
python3 ora_edit.py mask_element scene.png --mask tree_mask.png --entity "tree" --output scene_with_tree.ora
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
- Creates an entity group (or uses existing one)
|
||||
- Copies the specified source layer
|
||||
- Applies the mask as the alpha channel
|
||||
- Saves as `entity_N` (auto-incremented: door_0, door_1, etc.)
|
||||
|
||||
### Inspecting ORA Files
|
||||
|
||||
Display the layer structure and group hierarchy of an ORA file:
|
||||
|
||||
```bash
|
||||
python3 ora_edit.py inspect <ora_file>
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# View structure of an ORA file
|
||||
python3 ora_edit.py inspect scene.ora
|
||||
|
||||
# Check what's in a file before adding more elements
|
||||
python3 ora_edit.py inspect character.ora
|
||||
```
|
||||
|
||||
### Extracting Layers as PNG
|
||||
|
||||
Extract a specific layer from an ORA file and save it as a PNG:
|
||||
|
||||
```bash
|
||||
python3 ora_edit.py extract_png <ora_file> --layer <layer_name> [--output <output.png>]
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```bash
|
||||
# Extract a layer with default output name
|
||||
python3 ora_edit.py extract_png scene.ora --layer door_0
|
||||
|
||||
# Extract with custom output name
|
||||
python3 ora_edit.py extract_png scene.ora --layer background --output bg.png
|
||||
|
||||
# Extract all layers from an ORA (use with inspect)
|
||||
for layer in $(python3 ora_edit.py inspect scene.ora | grep "Layer" | awk '{print $NF}'); do
|
||||
python3 ora_edit.py extract_png scene.ora --layer "$layer" --output "${layer}.png"
|
||||
done
|
||||
```
|
||||
|
||||
**Output format:**
|
||||
```
|
||||
File: scene.ora
|
||||
|
||||
==================================================
|
||||
ORA STRUCTURE SUMMARY
|
||||
==================================================
|
||||
|
||||
📁 Group 1: door
|
||||
└─ Layer 1: door_0
|
||||
└─ Layer 2: door_1
|
||||
📁 Group 2: window
|
||||
└─ Layer 1: window_0
|
||||
🖼️ Base Layer 3: background
|
||||
|
||||
==================================================
|
||||
```
|
||||
|
||||
## Workflow Examples
|
||||
|
||||
### Example 1: Game Scene Composition
|
||||
|
||||
Building a scene with multiple masked elements:
|
||||
|
||||
```bash
|
||||
# Start with background
|
||||
python3 ora_edit.py create background.png scene.ora --layer-name "room"
|
||||
|
||||
# Add a door masked from the room layer
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask door_alpha.png \
|
||||
--entity "door" \
|
||||
--layer "room"
|
||||
|
||||
# Add a window
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask window_alpha.png \
|
||||
--entity "window" \
|
||||
--layer "room"
|
||||
|
||||
# Add another door variant (auto-increments to door_1)
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask door_open_alpha.png \
|
||||
--entity "door" \
|
||||
--layer "room"
|
||||
|
||||
# Check the final structure
|
||||
python3 ora_edit.py inspect scene.ora
|
||||
```
|
||||
|
||||
**Resulting structure:**
|
||||
```
|
||||
📁 Group: door
|
||||
└─ door_0
|
||||
└─ door_1
|
||||
📁 Group: window
|
||||
└─ window_0
|
||||
🖼️ Base Layer: room
|
||||
```
|
||||
|
||||
### Example 2: Character Animation
|
||||
|
||||
Creating animation frames with masked body parts:
|
||||
|
||||
```bash
|
||||
# Create base character
|
||||
python3 ora_edit.py create character_base.png character.ora --layer-name "body"
|
||||
|
||||
# Add masked arm that can be animated
|
||||
python3 ora_edit.py mask_element character.ora \
|
||||
--mask arm_mask.png \
|
||||
--entity "arm" \
|
||||
--layer "body"
|
||||
|
||||
# Add masked head
|
||||
python3 ora_edit.py mask_element character.ora \
|
||||
--mask head_mask.png \
|
||||
--entity "head" \
|
||||
--layer "body"
|
||||
```
|
||||
|
||||
### Example 3: AI-Generated Assets
|
||||
|
||||
Working with AI-generated masks:
|
||||
|
||||
```bash
|
||||
# Generate mask using ComfyUI or other tool
|
||||
python3 extract_mask.py "the wooden chest" scene.png chest_mask.png
|
||||
|
||||
# Add to ORA
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask chest_mask.png \
|
||||
--entity "chest" \
|
||||
--layer "background"
|
||||
```
|
||||
|
||||
### Example 4: Iterative Design
|
||||
|
||||
Refining elements with multiple mask attempts:
|
||||
|
||||
```bash
|
||||
# First iteration
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask door_v1.png \
|
||||
--entity "door" \
|
||||
--layer "background"
|
||||
|
||||
# Second iteration (creates door_1)
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask door_v2.png \
|
||||
--entity "door" \
|
||||
--layer "background"
|
||||
|
||||
# Third iteration (creates door_2)
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask door_v3.png \
|
||||
--entity "door" \
|
||||
--layer "background"
|
||||
```
|
||||
|
||||
The ORA now contains all three versions to compare in GIMP/Krita.
|
||||
|
||||
### Example 5: Layer-Based Masking
|
||||
|
||||
Using different source layers for different entities:
|
||||
|
||||
```bash
|
||||
# Create ORA with multiple base layers
|
||||
python3 ora_edit.py create day_scene.png scene.ora --layer-name "day"
|
||||
python3 ora_edit.py create night_scene.png scene_night.ora --layer-name "night"
|
||||
|
||||
# Extract and use specific layers
|
||||
# (Assume we've combined these into one ORA manually or via script)
|
||||
|
||||
# Mask using day layer
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask sun_mask.png \
|
||||
--entity "sun" \
|
||||
--layer "day"
|
||||
|
||||
# Mask using night layer
|
||||
python3 ora_edit.py mask_element scene.ora \
|
||||
--mask moon_mask.png \
|
||||
--entity "moon" \
|
||||
--layer "night"
|
||||
```
|
||||
|
||||
### Example 6: Exporting Layers for External Use
|
||||
|
||||
Extracting layers for use in other tools or workflows:
|
||||
|
||||
```bash
|
||||
# Check what layers exist
|
||||
python3 ora_edit.py inspect character.ora
|
||||
|
||||
# Extract specific animation frames
|
||||
python3 ora_edit.py extract_png character.ora --layer arm_0 --output arm_frame1.png
|
||||
python3 ora_edit.py extract_png character.ora --layer arm_1 --output arm_frame2.png
|
||||
|
||||
# Extract background for compositing
|
||||
python3 ora_edit.py extract_png scene.ora --layer background --output bg_composite.png
|
||||
```
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `create`
|
||||
|
||||
Create an ORA file from a PNG image.
|
||||
|
||||
```
|
||||
positional arguments:
|
||||
input_png Input PNG file
|
||||
output_ora Output ORA file (default: same name with .ora extension)
|
||||
|
||||
options:
|
||||
-h, --help Show help message
|
||||
--layer-name NAME Name for the root layer (default: base)
|
||||
```
|
||||
|
||||
### `mask_element`
|
||||
|
||||
Create a masked layer for an entity.
|
||||
|
||||
```
|
||||
positional arguments:
|
||||
input Input ORA or PNG file
|
||||
|
||||
options:
|
||||
-h, --help Show help message
|
||||
--mask MASK Mask file to use as alpha channel (required)
|
||||
--entity ENTITY Entity name/group name (required)
|
||||
--layer LAYER Source layer to copy and mask (default: base)
|
||||
--output OUTPUT Output ORA file (default: same as input)
|
||||
```
|
||||
|
||||
**Important behaviors:**
|
||||
- If input is PNG: Automatically converts to ORA first, using "base" as the layer name
|
||||
- Entity groups are created above base layers in the stack
|
||||
- Layer names auto-increment within groups (entity_0, entity_1, ...)
|
||||
- If the specified `--layer` doesn't exist, the command errors and lists available layers
|
||||
|
||||
### `inspect`
|
||||
|
||||
Display the structure of an ORA file without modifying it.
|
||||
|
||||
```
|
||||
positional arguments:
|
||||
ora_file ORA file to inspect
|
||||
|
||||
options:
|
||||
-h, --help Show help message
|
||||
```
|
||||
|
||||
**Output includes:**
|
||||
- File path
|
||||
- Entity groups with their layer counts
|
||||
- Base layers
|
||||
- Total layer/group statistics
|
||||
|
||||
### `extract_png`
|
||||
|
||||
Extract a layer from an ORA file as a PNG image.
|
||||
|
||||
```
|
||||
positional arguments:
|
||||
ora_file ORA file to extract from
|
||||
|
||||
options:
|
||||
-h, --help Show help message
|
||||
--layer LAYER Name of the layer to extract (required)
|
||||
--output OUTPUT Output PNG file (default: <layer_name>.png)
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
- Export layers for use in other graphics applications
|
||||
- Extract masked elements for game development
|
||||
- Create individual assets from composed ORA files
|
||||
- Backup or archive specific layers
|
||||
|
||||
**Important behaviors:**
|
||||
- If the specified `--layer` doesn't exist, the command errors and lists available layers
|
||||
- Output defaults to `<layer_name>.png` if not specified
|
||||
- Preserves transparency (RGBA) from the original layer
|
||||
|
||||
## Tips
|
||||
|
||||
### Mask Requirements
|
||||
- Masks can be grayscale (L mode) or RGB/RGBA
|
||||
- White = fully opaque, Black = fully transparent
|
||||
- Grayscale values create partial transparency
|
||||
|
||||
### Layer Organization
|
||||
- Entity groups appear first in the layer stack
|
||||
- Base layers appear at the end
|
||||
- This organization makes it easy to toggle entities on/off in GIMP/Krita
|
||||
|
||||
### Workflow Integration
|
||||
- Combine with `extract_mask.py` for AI-powered masking
|
||||
- Use `mask_to_polygon.py` to convert masks to Godot collision polygons
|
||||
- Chain multiple `mask_element` calls in shell scripts for batch processing
|
||||
|
||||
## Error Handling
|
||||
|
||||
The tool provides clear error messages:
|
||||
|
||||
```bash
|
||||
# Missing layer
|
||||
$ python3 ora_edit.py mask_element scene.ora --mask x.png --entity door --layer "missing"
|
||||
Error: Layer 'missing' not found in ORA file
|
||||
Available layers:
|
||||
- base
|
||||
- door_0
|
||||
- door_1
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Python 3.8+
|
||||
- Pillow (PIL)
|
||||
|
||||
Install dependencies:
|
||||
```bash
|
||||
pip install Pillow
|
||||
```
|
||||
|
||||
## ORA Format
|
||||
|
||||
OpenRaster (.ora) is an open standard for layered raster graphics. This tool creates ORA 0.0.3 compatible files that can be opened in:
|
||||
- GIMP (with ora plugin)
|
||||
- Krita
|
||||
- MyPaint
|
||||
- Other ORA-supporting applications
|
||||
|
||||
The generated structure:
|
||||
```
|
||||
archive.ora/
|
||||
├── mimetype # "image/openraster"
|
||||
├── stack.xml # Layer hierarchy
|
||||
├── mergedimage.png # Flattened preview
|
||||
├── Thumbnails/
|
||||
│ └── thumbnail.png # 256x256 preview
|
||||
└── data/
|
||||
├── base.png # Layer images
|
||||
└── entity/
|
||||
└── entity_0.png
|
||||
```
|
||||
Reference in New Issue
Block a user