Add Documentation
commit
f05beea06f
1 changed files with 191 additions and 0 deletions
191
Documentation.md
Normal file
191
Documentation.md
Normal file
|
|
@ -0,0 +1,191 @@
|
||||||
|
# PNG Metadata Editor - Technical Documentation
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Features](#features)
|
||||||
|
3. [Code Structure](#code-structure)
|
||||||
|
4. [Key Components](#key-components)
|
||||||
|
5. [Data Flow](#data-flow)
|
||||||
|
6. [API Reference](#api-reference)
|
||||||
|
7. [Usage Examples](#usage-examples)
|
||||||
|
8. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
PNG Metadata Editor is a graphical application built with Python and Tkinter that allows users to view, edit, add, and delete metadata in PNG files. The application leverages the Pillow library for PNG manipulation.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Core Functionality
|
||||||
|
- **Metadata Viewing**: Display all text chunks (tEXt, zTXt, iTXt) in PNG files
|
||||||
|
- **Metadata Editing**: Add, modify, and delete metadata fields
|
||||||
|
- **JSON Support**: Pretty-print JSON-formatted values
|
||||||
|
- **Clipboard Integration**: Copy metadata values to clipboard
|
||||||
|
|
||||||
|
### UI Features
|
||||||
|
- Split-pane view with tree and detail panels
|
||||||
|
- Status bar with temporary messages
|
||||||
|
- Unsaved changes indicator
|
||||||
|
- Responsive dialogs for adding/editing fields
|
||||||
|
|
||||||
|
## Code Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
png-meta-editor.py
|
||||||
|
├── PNGMetadataEditor (Main Class)
|
||||||
|
│ ├── __init__() - Initialization
|
||||||
|
│ ├── setup_ui() - UI Construction
|
||||||
|
│ ├── open_file() - File Operations
|
||||||
|
│ ├── save_changes() - Save Functionality
|
||||||
|
│ └── Various helper methods
|
||||||
|
└── Supporting Functions
|
||||||
|
├── format_value_for_display()
|
||||||
|
├── truncate_value()
|
||||||
|
└── mark_as_modified()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Components
|
||||||
|
|
||||||
|
### Main Application Class
|
||||||
|
```python
|
||||||
|
class PNGMetadataEditor:
|
||||||
|
def __init__(self, root):
|
||||||
|
# Initialize application state
|
||||||
|
self.current_file = None
|
||||||
|
self.metadata_dict = {}
|
||||||
|
self.has_unsaved_changes = False
|
||||||
|
```
|
||||||
|
|
||||||
|
### UI Components
|
||||||
|
- **Treeview**: Displays metadata keys with truncated values
|
||||||
|
- **Detail Text**: Shows full value of selected metadata
|
||||||
|
- **Status Bar**: Provides feedback messages
|
||||||
|
- **Dialogs**: Modal windows for adding/editing fields
|
||||||
|
|
||||||
|
### Data Handling
|
||||||
|
```python
|
||||||
|
def open_file(self):
|
||||||
|
"""Load PNG file and extract metadata"""
|
||||||
|
img = Image.open(filepath)
|
||||||
|
self.metadata_dict = dict(img.text) # Extract all text chunks
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
1. **File Opening**:
|
||||||
|
- User selects PNG file → `open_file()` called
|
||||||
|
- PIL extracts text chunks → stored in `metadata_dict`
|
||||||
|
- UI refreshed with new data
|
||||||
|
|
||||||
|
2. **Editing Process**:
|
||||||
|
- User selects field → `on_selection_change()` updates detail view
|
||||||
|
- Edit initiated → `edit_entry()` opens dialog
|
||||||
|
- Changes saved → `mark_as_modified()` updates state
|
||||||
|
|
||||||
|
3. **Saving**:
|
||||||
|
- User clicks Save → `save_changes()` called
|
||||||
|
- New PngInfo object created with updated metadata
|
||||||
|
- File saved with `img.save()` using new metadata
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### Public Methods
|
||||||
|
| Method | Description |
|
||||||
|
|--------|-------------|
|
||||||
|
| `open_file()` | Loads PNG file and extracts metadata |
|
||||||
|
| `save_changes()` | Saves current metadata to file |
|
||||||
|
| `add_field()` | Opens dialog to add new metadata field |
|
||||||
|
| `edit_entry()` | Opens dialog to edit selected field |
|
||||||
|
| `delete_field()` | Removes selected metadata field |
|
||||||
|
|
||||||
|
### Helper Methods
|
||||||
|
```python
|
||||||
|
def format_value_for_display(self, value):
|
||||||
|
"""Try to parse as JSON for pretty printing"""
|
||||||
|
try:
|
||||||
|
return json.dumps(json.loads(value), indent=2)
|
||||||
|
except:
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
def truncate_value(self, value, max_length=80):
|
||||||
|
"""Shorten long values for tree display"""
|
||||||
|
return str(value)[:max_length] + "..." if len(str(value)) > max_length else str(value)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Basic Workflow
|
||||||
|
```python
|
||||||
|
# Initialize application
|
||||||
|
root = tk.Tk()
|
||||||
|
app = PNGMetadataEditor(root)
|
||||||
|
|
||||||
|
# Open a file (simulated)
|
||||||
|
app.current_file = "example.png"
|
||||||
|
img = Image.open("example.png")
|
||||||
|
app.metadata_dict = dict(img.text)
|
||||||
|
app.refresh_tree()
|
||||||
|
|
||||||
|
# Edit a field
|
||||||
|
app.edit_entry() # Would normally be triggered by UI event
|
||||||
|
|
||||||
|
# Save changes
|
||||||
|
app.save_changes()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Programmatic Access
|
||||||
|
```python
|
||||||
|
# Get all metadata as dictionary
|
||||||
|
metadata = app.metadata_dict
|
||||||
|
|
||||||
|
# Add new field programmatically
|
||||||
|
app.metadata_dict["NewField"] = "Value"
|
||||||
|
app.mark_as_modified()
|
||||||
|
app.refresh_tree()
|
||||||
|
|
||||||
|
# Check for unsaved changes
|
||||||
|
if app.has_unsaved_changes:
|
||||||
|
print("There are unsaved changes!")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
1. **File Not Opening**:
|
||||||
|
- Ensure file is a valid PNG
|
||||||
|
- Check file permissions
|
||||||
|
|
||||||
|
2. **Metadata Not Displaying**:
|
||||||
|
- Verify PNG contains text chunks
|
||||||
|
- Check for special characters in keys/values
|
||||||
|
|
||||||
|
3. **Save Failures**:
|
||||||
|
- Ensure file isn't read-only
|
||||||
|
- Verify write permissions to directory
|
||||||
|
|
||||||
|
### Debugging Tips
|
||||||
|
- Check status bar for error messages
|
||||||
|
- Review console output for exceptions
|
||||||
|
- Verify metadata_dict contents in debugger
|
||||||
|
|
||||||
|
## Development Notes
|
||||||
|
|
||||||
|
### Design Decisions
|
||||||
|
1. **State Management**: Uses `has_unsaved_changes` flag to track modifications
|
||||||
|
2. **UI Separation**: Treeview and detail view maintain separate data representations
|
||||||
|
3. **Error Handling**: Graceful degradation with user-friendly messages
|
||||||
|
|
||||||
|
### Future Improvements
|
||||||
|
- Batch processing for multiple files
|
||||||
|
- Metadata validation rules
|
||||||
|
- Export/import to JSON
|
||||||
|
- Advanced search functionality
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
When contributing to this project:
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create a feature branch
|
||||||
|
3. Submit a pull request with tests
|
||||||
|
|
||||||
|
For major changes, please open an issue first to discuss what you would like to change.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue