zdraw 0.1.3.8
A high-performance drawing library for AI vision tasks, bounding boxes, and keypoints.
Requires Python: >=3.8

![PyPI Version](https://img.shields.io/pypi/v/zdraw)
# ZDraw

ZDraw is a powerful Python library for drawing custom bounding boxes with rounded corners on images using OpenCV. It features advanced multi-label support, metadata-style panels, PNG icon integration, and intelligent dynamic sizing for professional computer vision applications.

## Features

### Core Drawing Capabilities
- **Rounded rectangles** with dynamic corner radius and border thickness
- **Premium "Tinted Glass" aesthetics** - Labels feature a rich, semi-transparent background tinted with the class color
- **Universal shape drawing** (lines, triangles, rectangles, polygons)
- **Keypoint visualization** with skeleton connections
- **Smart color management** with automatic class-to-color mapping
- **Multi-line text drawing** with dynamic background and styling (ZDrawText)

15: ### Advanced Label System (ZDrawRectCustom)




166: - `shape`: Optional shape type for validation
167: - `return_original_frame`: Whether to return original frame
168: 
#### `ZDrawText(frame, text, x, y, color=None, bg_color=None, font_scale=None, thickness=None, padding=5, line_spacing=5, return_original_frame=False)`
Draws multi-line text with customizable background and styling.

**Parameters:**
- `frame`: Input image frame
- `text`: Text string (can include newlines `\n`)
- `x, y`: Top-left coordinates
- `color`: Text color (BGR tuple). Defaults to white.
- `bg_color`: Background color (BGR tuple). If None, no background is drawn.
- `font_scale`: Font scale (auto-calculated if None)
- `thickness`: Thickness (auto-calculated if None)
- `padding`: Padding around text for background
- `line_spacing`: Spacing between lines
- `return_original_frame`: Whether to return original frame

#### `ZDrawKeypoints(frame, keypoints, skeleton=None, point_color=(0, 255, 255), line_color=(255, 0, 0), radius=3, thickness=2)`
Draws keypoints with optional skeleton connections.
- **Multi-label support** - Display multiple labels per bounding box
- **Metadata-style panels** - Unified background for all labels (like professional CV applications)
- **PNG icon support** - Add icons next to labels with full transparency support
- **Dynamic positioning** - Auto-detection of optimal label placement
- **Smart text handling** - Automatic truncation for long labels
- **Responsive sizing** - Font and spacing adapt to frame and bounding box dimensions
- **Boundary-aware** - Prevents labels from extending outside frame boundaries

## Installation

```bash
pip install zdraw
```

## Quick Start

### Basic Bounding Box with Label

```python
import cv2
from zdraw import ZDraw

# Initialize ZDraw
zdraw = ZDraw()

# Load an image
frame = cv2.imread("image.jpg")
frame = cv2.resize(frame, (800, 600), interpolation=cv2.INTER_AREA)

# Draw simple bounding box with label
x1, y1, x2, y2 = 100, 150, 400, 300
frame = zdraw.ZDrawRect(frame, x1, y1, x2, y2, class_name="person")
```

### Advanced Multi-Label with Metadata Style

```python
# PPE Detection with metadata-style panel
frame = zdraw.ZDrawRectCustom(
    frame, x1, y1, x2, y2,
    main_class="person",
    sub_labels=["helmet", "safety_vest", "steel_boots"],
    metadata_style=True,  # Unified background panel
    label_position="auto"  # Smart positioning
)

# With PNG icons (optional)
icons = {
    "person": "icons/person.png",
    "helmet": "icons/helmet.png",
    "safety_vest": "icons/vest.png"
}

frame = zdraw.ZDrawRectCustom(
    frame, x1, y1, x2, y2,
    main_class="person",
    sub_labels=["helmet", "safety_vest"],
    metadata_style=True,
    icons=icons,  # Optional PNG icons
    label_position="outside_top"
)
```

## Usage Examples

### Shape Drawing

```python
# Draw various shapes
line_points = [(50, 50), (200, 50)]
triangle_points = [(250, 100), (350, 100), (300, 200)]
rectangle_points = [(50, 300), (200, 300), (200, 400), (50, 400)]

frame = zdraw.ZDrawShape(frame, line_points, shape="line")
frame = zdraw.ZDrawShape(frame, triangle_points, shape="triangle")
frame = zdraw.ZDrawShape(frame, rectangle_points, shape="rectangle")

### Line Drawing with Endpoints
```python
# Draw a line with endpoints (using unpacked coordinates)
frame = zdraw.ZDrawLine(frame, 50, 50, 200, 200, color=(0, 255, 0), thickness=3, draw_points=True)

# Draw a line using points tuple
pt1 = (300, 50)
pt2 = (450, 200)
frame = zdraw.ZDrawLine(frame, pt1, pt2, color=(0, 0, 255), thickness=2)
```
```

### Text Drawing

```python
# Draw multi-line text with background
frame = zdraw.ZDrawText(
    frame, 
    "Analysis Result:\n- Person: 98%\n- Helmet: Yes", 
    x=50, y=50,
    color=(255, 255, 255),
    bg_color=(0, 0, 0),
    padding=10
)
```

### PPE Detection Example

```python
# Real-world PPE monitoring scenario
frame = zdraw.ZDrawRectCustom(
    frame, 100, 100, 300, 400,
    main_class="person",
    sub_labels=["helmet", "vest", "boots"],
    metadata_style=True,
    label_position="auto"
)

# Violation detection
frame = zdraw.ZDrawRectCustom(
    frame, 400, 100, 600, 400,
    main_class="person",
    sub_labels=["violator"],
    metadata_style=True,
    label_position="outside_top"
)
```

## API Reference

### Core Methods

#### `ZDraw(class_colors=None)`
Initializes the ZDraw object.

**Parameters:**
- `class_colors` (dict, optional): Dictionary mapping class names to RGB tuples

#### `ZDrawRect(frame, x1, y1, x2, y2, class_name=None, color=None, return_original_frame=False)`
Draws a simple bounding box with optional label.

**Parameters:**
- `frame`: Input image frame
- `x1, y1, x2, y2`: Bounding box coordinates
- `class_name`: Optional class label
- `color`: Optional color override
- `return_original_frame`: Whether to return original frame

#### `ZDrawRectCustom(frame, x1, y1, x2, y2, main_class, sub_labels=None, color=None, label_position="auto", metadata_style=True, icons=None, return_original_frame=False)`
Enhanced bounding box with multi-label support and metadata-style panels.

**Parameters:**
- `frame`: Input image frame
- `x1, y1, x2, y2`: Bounding box coordinates
- `main_class`: Primary class label
- `sub_labels`: List of additional labels
- `color`: Optional color override
- `label_position`: Label positioning ("auto", "inside", "outside_top", "outside_bottom", "outside_left", "outside_right")
- `metadata_style`: If True, displays unified metadata panel (default: True)
- `icons`: Dictionary mapping label names to PNG icon file paths (optional)
- `return_original_frame`: Whether to return original frame

#### `ZDrawShape(frame, points, shape=None, return_original_frame=False)`
Draws universal shapes (lines, triangles, rectangles, polygons).

**Parameters:**
- `frame`: Input image frame
- `points`: List of points defining the shape
- `shape`: Optional shape type for validation
- `return_original_frame`: Whether to return original frame

#### `ZDrawKeypoints(frame, keypoints, skeleton=None, point_color=(0, 255, 255), line_color=(255, 0, 0), radius=3, thickness=2)`
Draws keypoints with optional skeleton connections.

**Parameters:**
- `frame`: Input image frame
- `keypoints`: List of (x, y, visibility) tuples
- `skeleton`: Optional list of (idx1, idx2) connections
- `point_color`: Color for keypoints
- `line_color`: Color for skeleton lines
- `thickness`: Line thickness
- `radius`: Keypoint radius

#### `ZDrawLine(frame, *args, color=None, thickness=2, draw_points=False, point_radius=None, return_original_frame=False)`
Draws a line with flexible coordinate inputs and optional endpoint circles.

**Parameters:**
- `frame`: Input image frame.
- `*args`: Coordinates defining the line. Can be:
    - 4 arguments: `x1, y1, x2, y2`
    - 2 arguments: `(x1, y1), (x2, y2)`
    - 1 argument: `[(x1, y1), (x2, y2)]`
- `color`: Color (BGR). Defaults to white.
- `thickness`: Line thickness.
- `draw_points`: If True, draws filled circles at endpoints.
- `point_radius`: Radius of endpoint circles. Defaults to `thickness + 3`.
- `return_original_frame`: Whether to return original frame.

### Label Positioning Options

- `"auto"`: Automatically chooses the best position based on available space
- `"inside"`: Places labels inside the bounding box
- `"outside_top"`: Places labels above the bounding box
- `"outside_bottom"`: Places labels below the bounding box
- `"outside_left"`: Places labels to the left of the bounding box
- `"outside_right"`: Places labels to the right of the bounding box

### Icon Support

Icons should be PNG files with transparency support. The `icons` parameter accepts a dictionary mapping label names to file paths:

```python
icons = {
    "person": "path/to/person.png",
    "helmet": "path/to/helmet.png",
    "vest": "path/to/vest.png"
}
```

### Dependencies

- Python 3.8 or higher
- OpenCV (opencv-python)
- NumPy

## License

This project is licensed under the MIT License. See the LICENSE file for details.