### Provide Default Example Input Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Use `example_inputs` to get default example input for testing and documentation. It returns a dictionary with an example image URL and a sample bounding box. ```python def example_inputs(self) -> Any: """Provides default example input for testing and documentation purposes.""" pass ``` -------------------------------- ### Process Example Images Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Use `process_example` to process example images for the component's display. It handles example annotation dictionaries containing an image and optional boxes. ```python def process_example(self, value: dict | None) -> FileData | None: """Processes example images for the component's example display.""" pass ``` -------------------------------- ### process_example Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Processes example images for the component's example display. This method takes an example annotation dictionary and returns a FileData object suitable for displaying the image. ```APIDOC ## process_example ### Description Processes example images for the component's example display. ### Method Signature `process_example(self, value: dict | None) -> FileData | None` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **value** (`dict | None`) - Required/Optional - Example annotation dictionary with image and optional boxes. ### Response #### Success Response - **FileData | None** - File data object for the image. ### Raises - `ValueError`: If image is missing. ``` -------------------------------- ### example_inputs Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Provides default example input for testing and documentation purposes. This method returns a dictionary containing an example image URL and a sample bounding box with its label and color. ```APIDOC ## example_inputs ### Description Provides default example input for testing and documentation purposes. ### Method Signature `example_inputs(self) -> Any` ### Parameters None ### Response #### Success Response - **dict** - Dictionary with example image URL and sample bounding box with label and color. ### Raises None ``` -------------------------------- ### Install gradio_image_annotation Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/README.md Install the package using pip. This is the first step to using the component in your Python projects. ```bash pip install gradio_image_annotation ``` -------------------------------- ### Basic Image Annotator Setup Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Demonstrates how to initialize the image annotator with a list of labels and their corresponding colors. ```python import gradio as gr from gradio_image_annotation import image_annotator with gr.Blocks() as demo: annotator = image_annotator( label_list=["Person", "Vehicle", "Building"], label_colors=[(0, 255, 0), (255, 0, 0), (0, 0, 255)] ) demo.launch() ``` -------------------------------- ### Full Bounding Box Specification Example Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/types.md This example demonstrates a bounding box with all optional fields specified, including a label and an RGB color. The color is provided as a tuple of integers. ```python {"xmin": 10, "ymin": 20, "xmax": 100, "ymax": 150, "label": "Person", "color": (255, 0, 0)} ``` -------------------------------- ### Using change event with multiple outputs Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md Example demonstrating how to use the 'change' event with multiple output components, updating a box count and a preview image. ```APIDOC ## Using change event with multiple outputs ### Description Connects the `change` event of an annotator component to update multiple output components: a `gr.Number` for box count and a `gr.Image` for preview. ### Event `annotator.change(on_change, annotator, [box_count, preview])` ### Handler Function (`on_change`) ```python def on_change(annotations): count = 0 preview_img = None if annotations: count = len(annotations.get("boxes", [])) preview_img = annotations["image"] return count, preview_img # Must match output order ``` ### Parameters * **`annotator`**: The input `image_annotator` component. * **`box_count`**: A `gr.Number` component to display the count of boxes. * **`preview`**: A `gr.Image` component to display a preview of the annotated image. ``` -------------------------------- ### Start Image Panning Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/window_viewer.md Initiates a panning operation by recording the starting mouse coordinates and attaching necessary event handlers for drag movement and release. ```typescript startDrag(event: MouseEvent): void ``` -------------------------------- ### Basic Image Annotator Setup with Labels Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md Standard object detection UI where users label objects. Use `label_list` for dropdowns, `label_colors` to color-code labels, and `box_min_size` to prevent tiny boxes. ```python import gradio as gr from gradio_image_annotation import image_annotator with gr.Blocks() as demo: annotator = image_annotator( label_list=["Person", "Vehicle", "Building"], label_colors=[(0, 255, 0), (255, 0, 0), (0, 0, 255)], box_min_size=20, ) demo.launch() ``` -------------------------------- ### BaseExample Component Properties Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/frontend/shared/patched_dropdown/README.md Defines the properties for a BaseExample component, likely used for displaying example data. ```javascript export let value: string; export let type: "gallery" | "table"; export let selected = false; ``` -------------------------------- ### Using upload event with input/output Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md Example demonstrating how to use the 'upload' event to process uploaded image annotations and update a filename textbox and metadata JSON. ```APIDOC ## Using upload event with input/output ### Description Connects the `upload` event of an annotator component to update a `gr.Textbox` for filename and a `gr.JSON` for metadata. ### Event `annotator.upload(on_upload, annotator, [filename, metadata])` ### Handler Function (`on_upload`) ```python def on_upload(annotations): if not annotations: return "", {} # Get filename from UI or metadata return "unknown.jpg", {"boxes": len(annotations.get("boxes", []))} ``` ### Parameters * **`annotator`**: The input `image_annotator` component. * **`filename`**: A `gr.Textbox` component to display the filename. * **`metadata`**: A `gr.JSON` component to display metadata about the annotations. ``` -------------------------------- ### Multi-Step Workflow with Gradio Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md This example illustrates a multi-step workflow for image annotation. It updates a textbox to display the current stage of the process based on user interactions like uploading an image or changing annotations. ```python annotator = image_annotator() stage_display = gr.Textbox(label="Current Stage") def on_upload(annotations): return gr.update(value="Stage 1: Image loaded") def on_change(annotations): if not annotations: return box_count = len(annotations.get("boxes", [])) if box_count == 0: return gr.update(value="Stage 1: Ready for annotations") elif box_count < 5: return gr.update(value=f"Stage 2: {box_count} boxes - add more") else: return gr.update(value="Stage 3: Ready to submit") annotator.upload(on_upload, annotator, stage_display) annotator.change(on_change, annotator, stage_display) ``` -------------------------------- ### Object Detection Setup with Custom Labels and Colors Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/configuration.md Configure the annotator for object detection by providing a list of labels and corresponding RGB colors. Adjusts box and handle sizes, and enables keyboard shortcuts. ```python annotator = image_annotator( label_list=["person", "car", "bicycle", "dog"], label_colors=[ (0, 255, 0), # Green for person (255, 0, 0), # Red for car (0, 0, 255), # Blue for bicycle (255, 255, 0), # Yellow for dog ], box_min_size=20, handle_size=10, enable_keyboard_shortcuts=True, ) ``` -------------------------------- ### Minimal Bounding Box Example Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/types.md A minimal valid bounding box requires only the xmin, ymin, xmax, and ymax coordinates. This example shows the essential fields for defining a box. ```python {"xmin": 10, "ymin": 20, "xmax": 100, "ymax": 150} ``` -------------------------------- ### Gradio Component Hierarchy Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/README.md Illustrates the main component's methods for preprocessing, postprocessing, and handling example data. ```plaintext image_annotator (Gradio Component) ├── preprocess() → AnnotatedImageValue ├── postprocess() → AnnotatedImageData └── process_example() → FileData ``` -------------------------------- ### AnnotatedImageData Validation Examples Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/annotated_image_data.md Demonstrates how the AnnotatedImageData model validates input data, showing examples of invalid data that would raise errors and a valid data structure. ```python # Would raise validation error AnnotatedImageData( image="not a FileData", # ❌ Wrong type boxes=[], orientation=0 ) ``` ```python # Would raise validation error AnnotatedImageData( image=FileData(...), boxes="not a list", # ❌ Wrong type orientation=0 ) ``` ```python # Valid AnnotatedImageData( image=FileData(path="/tmp/image.png", orig_name="photo.jpg"), boxes=[], orientation=0 ) ``` -------------------------------- ### Initiate Box Creation Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Starts the process of creating a new box. Attaches event listeners for mouse movement and release, storing initial canvas coordinates. ```typescript startCreating(event: MouseEvent, canvasX: number, canvasY: number): void ``` -------------------------------- ### startDrag Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/window_viewer.md Initiates the panning operation by recording the starting mouse coordinates and attaching necessary event handlers for drag movement and release. ```APIDOC ## startDrag ### Description Initiates panning operation. Records starting position and attaches event handlers. ### Method `startDrag(event: MouseEvent): void` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - `event` (`MouseEvent`): The pointerdown or mousedown event. ### Returns - `void` ### Side Effects - Sets `isDragging = true` - Sets `startDragX`, `startDragY` from event coordinates - Attaches document-level pointermove and pointerup handlers ``` -------------------------------- ### Process Annotations with gr.Button Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md Trigger annotation processing when a gr.Button is clicked. This example shows how to process annotations on button click or on change. ```python annotator = image_annotator() process_btn = gr.Button("Process Annotations") output = gr.JSON() def process(annotations): if not annotations: return {"error": "No image"} return {"boxes": len(annotations.get("boxes", []))} # Process only on button click, not on every change process_btn.click(process, annotator, output) # OR: Process on change annotator.change(process, annotator, output) ``` -------------------------------- ### Box Data Structure Example Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Defines the required and optional fields for a bounding box dictionary used in image annotation. Ensure all required fields (xmin, ymin, xmax, ymax) are provided. ```python { "xmin": int, # Left edge x-coordinate (required) "ymin": int, # Top edge y-coordinate (required) "xmax": int, # Right edge x-coordinate (required) "ymax": int, # Bottom edge y-coordinate (required) "label": str, # Box label (optional, default "") "color": tuple[int, ...], # RGB color tuple (optional, default (0,0,0)) } ``` -------------------------------- ### Multi-step Workflow with Gradio Image Annotator Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md Guides users through a multi-step process by dynamically updating a stage indicator based on annotation progress. Bind to both 'upload' and 'change' events to track user interactions. ```python import gradio as gr from gradio_image_annotation import image_annotator def compute_statistics(annotations): """Compute stats from annotation.""" if not annotations: stage = "Stage 1: Upload an image" else: boxes = annotations.get("boxes", []) if not boxes: stage = "Stage 2: Draw bounding boxes" elif len(boxes) < 3: stage = f"Stage 3: Add more boxes ({len(boxes)}/3 minimum)" else: stage = "Stage 4: Ready to submit!" return stage with gr.Blocks() as demo: gr.Markdown("# Object Annotation Workflow") annotator = image_annotator( label_list=["Person", "Vehicle"], label_colors=[(0, 255, 0), (255, 0, 0)] ) stage_display = gr.Textbox( label="Current Stage", value="Stage 1: Upload an image", interactive=False ) annotator.upload(compute_statistics, annotator, stage_display) annotator.change(compute_statistics, annotator, stage_display) ``` -------------------------------- ### Programmatic Construction of AnnotatedImageData Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/annotated_image_data.md In advanced scenarios, AnnotatedImageData can be constructed programmatically for direct use. This example shows how to create an instance with FileData, box definitions, and orientation, then pass it to the component's preprocess method. ```python from gradio.data_classes import FileData from gradio_image_annotation.image_annotator import AnnotatedImageData # Programmatically create (not typical) data = AnnotatedImageData( image=FileData(path="/path/to/image.png", orig_name="image.png"), boxes=[ { "xmin": 100, "ymin": 150, "xmax": 300, "ymax": 400, "label": "Region", "color": "rgb(255, 0, 0)", "scaleFactor": 1.0 } ], orientation=1 ) # Pass to component's preprocess annotator = image_annotator() result = annotator.preprocess(data) # result is AnnotatedImageValue ``` -------------------------------- ### Process Annotation Changes Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/README.md Set up a callback function to process annotation data whenever changes occur in the image annotator. This example demonstrates how to count the number of annotated boxes and display the count in a textbox. ```python annotator = image_annotator() def process(annotations): if not annotations: return None boxes = annotations.get("boxes", []) return f"Annotated {len(boxes)} boxes" output = gr.Textbox() annotator.change(process, annotator, output) ``` -------------------------------- ### startCreating Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Initiates the box creation process. This method sets up the necessary state and attaches event listeners for drawing a new box. ```APIDOC ## startCreating ### Description Initiates box creation mode. Attaches move and release listeners. ### Method Signature ```typescript startCreating(event: MouseEvent, canvasX: number, canvasY: number): void ``` ### Parameters #### Path Parameters - `event` (MouseEvent) - Required - Mouse down event. - `canvasX` (number) - Required - Canvas-relative starting x. - `canvasY` (number) - Required - Canvas-relative starting y. ``` -------------------------------- ### Minimal Image Annotator Configuration Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/configuration.md Initialize the annotator with default settings. Ensure Gradio and the annotator library are imported. ```python from gradio_image_annotation import image_annotator import gradio as gr # Absolute minimum - uses all defaults annotator = image_annotator() ``` -------------------------------- ### Image Annotator with Pre-loaded Annotations Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Shows how to initialize the image annotator with existing annotation data, including image source and box definitions. ```python example_data = { "image": "https://example.com/photo.jpg", "boxes": [ { "xmin": 100, "ymin": 150, "xmax": 300, "ymax": 400, "label": "Person", "color": (0, 255, 0) } ] } annotator = image_annotator(value=example_data) ``` -------------------------------- ### AnnotatedImageValue Usage Example Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/types.md Demonstrates how to process AnnotatedImageValue in a user-defined prediction function. Handles potential absence of annotations and extracts image shape. ```python def process_annotations(value: AnnotatedImageValue | None) -> dict: if not value: return {"error": "No annotations provided"} image = value["image"] boxes = value.get("boxes", []) return {"box_count": len(boxes), "image_shape": image.shape} ``` -------------------------------- ### Using Upload Event with Input/Output Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md Shows how to use the 'upload' event to process newly uploaded image annotations and update input/output components like textboxes and JSON displays. ```python annotator = image_annotator() filename = gr.Textbox(label="Filename") metadata = gr.JSON() def on_upload(annotations): if not annotations: return "", {} # Get filename from UI or metadata return "unknown.jpg", {"boxes": len(annotations.get("boxes", []))} annotator.upload( on_upload, annotator, [filename, metadata] ) ``` -------------------------------- ### Label Colors Configuration and Conversion Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/data-formats.md Illustrates configuring label colors using a mix of RGB tuples and hex strings, showing their internal conversion to uniform hex strings for frontend use. ```python # User configuration: annotator = image_annotator( label_list=["Person", "Car", "Building"], label_colors=[ (0, 255, 0), # Green for Person (255, 0, 0), # Red for Car "#0000FF" # Blue for Building (hex) ] ) # Internally stored after conversion: { "label_list": [("Person", 0), ("Car", 1), ("Building", 2)], "label_colors": ["#00ff00", "#ff0000", "#0000ff"] # All converted to hex } # Frontend receives: { "labelList": ["Person", "Car", "Building"], "labelColors": ["#00ff00", "#ff0000", "#0000ff"] } ``` -------------------------------- ### Get Box Height Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Calculates and returns the current height of the box in scaled display coordinates. This is useful for layout calculations or displaying dimensions. ```typescript getHeight(): number ``` -------------------------------- ### Get Box Width Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Calculates and returns the current width of the box in scaled display coordinates. This is useful for layout calculations or displaying dimensions. ```typescript getWidth(): number ``` -------------------------------- ### startResize Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Initiates a box resizing operation by specifying the handle index and the initial mouse event. ```APIDOC ## startResize ### Description Initiates resize operation on a specific handle. ### Method Signature ```typescript startResize(handleIndex: number, event: MouseEvent): void ``` ### Parameters #### Path Parameters - `handleIndex` (number) - Required - Index of handle being resized (0-7). - `event` (MouseEvent) - Required - Mouse down event. ``` -------------------------------- ### WindowViewer Initialization and Basic Usage Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/window_viewer.md Instantiate WindowViewer with a render callback and active pointers. Set image dimensions, resize the canvas, and handle user interactions like panning and zooming. ```typescript const windowViewer = new WindowViewer( () => canvas.render(), // renderCallBack pointersCache // active pointers ); // Set image dimensions windowViewer.imageWidth = 1920; windowViewer.imageHeight = 1080; // Resize canvas windowViewer.resize(800, 600); // User drags to pan // document.addEventListener("pointerdown", e => { // windowViewer.startDrag(e); // }); // User zooms (typically via wheel or pinch) // windowViewer.scale = 1.5; // windowViewer.renderCallBack(); // Rotate image // windowViewer.orientation = 1; // windowViewer.setRotatedImage(rotatedImgElement); ``` -------------------------------- ### Get Box Area Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Calculates and returns the current area of the box in scaled display coordinates. This can be used for various geometric calculations or display purposes. ```typescript getArea(): number ``` -------------------------------- ### Using Change Event with Multiple Outputs Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md Demonstrates how to use the 'change' event to update multiple output components. The handler function must return values in an order that matches the list of output components. ```python annotator = image_annotator() box_count = gr.Number(label="Box Count") preview = gr.Image(label="Preview") def on_change(annotations): count = 0 preview_img = None if annotations: count = len(annotations.get("boxes", [])) preview_img = annotations["image"] return count, preview_img # Must match output order annotator.change( on_change, annotator, [box_count, preview] # Multiple outputs ) ``` -------------------------------- ### handleCreating Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Handles mouse movement events during the box creation phase, dynamically updating the box's dimensions as the user drags. ```APIDOC ## handleCreating ### Description Handles pointer move while creating a box. Only processes if a single pointer is active. ### Method Signature ```typescript handleCreating(event: MouseEvent): void ``` ### Parameters #### Path Parameters - `event` (MouseEvent) - Required - Mouse move event. ``` -------------------------------- ### Image Annotator User Function Signature Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/README.md Example of a user function signature for the Image Annotator when used as both an input and output. It specifies the expected input type and return type. ```python def predict( value: AnnotatedImageValue | None ) -> dict | None: return value ``` -------------------------------- ### Box Constructor Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Initializes a new Box instance with specified properties and callbacks for rendering and creation completion. ```APIDOC ## Constructor Box ### Description Initializes a new Box instance with specified properties and callbacks for rendering and creation completion. ### Parameters #### Path Parameters - **renderCallBack** (`() => void`) - Required - Callback function invoked to trigger canvas re-render after any state change. - **onFinishCreation** (`() => void`) - Required - Callback function invoked when box creation completes. - **canvasWindow** (`WindowViewer`) - Required - Reference to WindowViewer managing zoom/pan state. - **pointersCache** (`Map`) - Required - Map of active pointer IDs to PointerEvent objects for multi-touch. - **canvasXmin** (`number`) - Required - Canvas bounding box left edge in pixels. - **canvasYmin** (`number`) - Required - Canvas bounding box top edge in pixels. - **canvasXmax** (`number`) - Required - Canvas bounding box right edge in pixels. - **canvasYmax** (`number`) - Required - Canvas bounding box bottom edge in pixels. - **label** (`string`) - Required - Text label for the box. - **xmin** (`number`) - Required - Box left edge x-coordinate in image pixels. - **ymin** (`number`) - Required - Box top edge y-coordinate in image pixels. - **xmax** (`number`) - Required - Box right edge x-coordinate in image pixels. - **ymax** (`number`) - Required - Box bottom edge y-coordinate in image pixels. - **color** (`string`) - Optional - CSS rgb or rgba color string. Example: `"rgb(255, 0, 0)"`. Default: `"rgb(255, 255, 255)"`. - **alpha** (`number`) - Optional - Fill opacity 0-1 (separate from color alpha). Default: `0.5`. - **minSize** (`number`) - Optional - Minimum box size in pixels (after scaling). Default: `25`. - **handleSize** (`number`) - Optional - Resize handle size in pixels. Default: `8`. - **thickness** (`number`) - Optional - Outline stroke width when not selected. Default: `2`. - **selectedThickness** (`number`) - Optional - Outline stroke width when selected. Default: `4`. - **scaleFactor** (`number`) - Optional - Scale factor for coordinate conversion (image display scale). Default: `1`. ``` -------------------------------- ### Image Annotator with Pre-loaded Annotations Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md Supports review/correction workflows starting with AI predictions. Users can refine pre-loaded boxes. Accepts numpy arrays, PIL Images, or URLs. ```python import numpy as np from PIL import Image import gradio as gr from gradio_image_annotation import image_annotator # Load from file image = Image.open("photo.jpg") # Convert to numpy if needed image_np = np.array(image) # Pre-annotated boxes initial_annotation = { "image": image_np, "boxes": [ {"xmin": 100, "ymin": 150, "xmax": 300, "ymax": 350, "label": "Person", "color": (0, 255, 0)}, {"xmin": 400, "ymin": 200, "xmax": 550, "ymax": 450, "label": "Car", "color": (255, 0, 0)}, ] } with gr.Blocks() as demo: annotator = image_annotator(value=initial_annotation) ``` -------------------------------- ### Initialize Image Annotator Component Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/README.md Instantiate the image annotator component with a predefined list of labels and their corresponding colors. This sets up the available annotation categories for the user. ```python from gradio_image_annotation import image_annotator import gradio as gr with gr.Blocks() as demo: annotator = image_annotator( label_list=["Person", "Vehicle"], label_colors=[(0, 255, 0), (255, 0, 0)] ) ``` -------------------------------- ### Basic Image Annotator Configuration Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/INDEX.md Configure the image annotator with a list of labels and their corresponding colors. Ensure labels and colors are provided as lists. ```python image_annotator( label_list=["A", "B"], label_colors=[(0, 255, 0), (255, 0, 0)] ) ``` -------------------------------- ### Perform Conditional Processing Based on Event Data Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/events.md Execute specific logic based on the content of event data. This example crops an image based on the first detected bounding box. ```python annotator = image_annotator(single_box=True) cropped_image = gr.Image(label="Cropped") def crop_image(annotations): if not annotations or not annotations.get("boxes"): return None box = annotations["boxes"][0] img = annotations["image"] # Numpy format: slice the array if isinstance(img, np.ndarray): return img[box["ymin"]: box["ymax"], box["xmin"]: box["xmax"]] return None annotator.change(crop_image, annotator, cropped_image) ``` -------------------------------- ### User Annotation Creation and Conversion Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/data-formats.md Demonstrates a user creating an annotation with an RGB tuple color and how it's converted internally to a CSS RGB string and then serialized to JSON. ```python # User code: import numpy as np image = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8) user_output = { "image": image, "boxes": [ {"xmin": 100, "ymin": 50, "xmax": 300, "ymax": 200, "label": "Person", "color": (0, 255, 0)} ], "orientation": 0 } # Postprocess converts: internal = { "image": {"path": "/tmp/cache/xyz.png", "orig_name": None}, "boxes": [ {"xmin": 100, "ymin": 50, "xmax": 300, "ymax": 200, "label": "Person", "color": "rgb(0, 255, 0)", "scaleFactor": 1.0} ], "orientation": 0 } # Serialized to JSON: json_data = { "image": {"path": "/tmp/cache/xyz.png", "orig_name": null}, "boxes": [ {"xmin": 100, "ymin": 50, "xmax": 300, "ymax": 200, "label": "Person", "color": "rgb(0, 255, 0)", "scaleFactor": 1.0} ], "orientation": 0 } # Sent to frontend, stored in Box objects ``` -------------------------------- ### Catch ValueError During Constructor Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/errors.md Always catch ValueError when creating components with user-provided parameters to handle invalid configurations gracefully. This example shows falling back to defaults if an error occurs. ```python try: annotator = image_annotator( image_type=user_input, label_list=user_labels, label_colors=user_colors ) except ValueError as e: print(f"Invalid configuration: {e}") # Fall back to defaults annotator = image_annotator() ``` -------------------------------- ### Basic Image Annotation with Gradio Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/README.md Demonstrates how to use the image_annotator component for object annotation. It requires Gradio and numpy. Predefined labels and colors can be set. ```python import gradio as gr from gradio_image_annotation import image_annotator import numpy as np example_annotation = { "image": "https://raw.githubusercontent.com/edgarGracia/gradio_image_annotator/refs/heads/main/demo/images/base.png", "boxes": [ { "xmin": 636, "ymin": 575, "xmax": 801, "ymax": 697, "label": "Vehicle", "color": (255, 0, 0) }, { "xmin": 360, "ymin": 615, "xmax": 386, "ymax": 702, "label": "Person", "color": (0, 255, 0) } ] } examples_crop = [ { "image": "https://raw.githubusercontent.com/gradio-app/gradio/main/guides/assets/logo.png", "boxes": [ { "xmin": 30, "ymin": 70, "xmax": 530, "ymax": 500, "color": (100, 200, 255), } ], }, { "image": "https://raw.githubusercontent.com/edgarGracia/gradio_image_annotator/refs/heads/main/demo/images/base.png", "boxes": [ { "xmin": 636, "ymin": 575, "xmax": 801, "ymax": 697, "color": (255, 0, 0), }, ], }, ] def crop(annotations): if angle := annotations.get("orientation", None): annotations["image"] = np.rot90(annotations["image"], k=-angle) if annotations["boxes"]: box = annotations["boxes"][0] return annotations["image"][ box["ymin"]: box["ymax"], box["xmin"]: box["xmax"] ] return None def get_boxes_json(annotations): return annotations["boxes"] with gr.Blocks() as demo: with gr.Tab("Object annotation", id="tab_object_annotation"): annotator = image_annotator( example_annotation, label_list=["Person", "Vehicle"], label_colors=[(0, 255, 0), (255, 0, 0)], ) button_get = gr.Button("Get bounding boxes") json_boxes = gr.JSON() button_get.click(get_boxes_json, annotator, json_boxes) with gr.Tab("Crop", id="tab_crop"): with gr.Row(): annotator_crop = image_annotator( examples_crop[0], image_type="numpy", disable_edit_boxes=True, single_box=True, ) image_crop = gr.Image() button_crop = gr.Button("Crop") button_crop.click(crop, annotator_crop, image_crop) gr.Examples(examples_crop, annotator_crop) with gr.Accordion("Keyboard Shortcuts"): gr.Markdown(""" - ``C``: Create mode - ``D``: Drag mode - ``E``: Edit selected box (same as double-click a box) - ``Delete``: Remove selected box - ``Space``: Reset view (zoom/pan) - ``Enter``: Confirm modal dialog - ``Escape``: Cancel/close modal dialog """ ) if __name__ == "__main__": demo.launch() ``` -------------------------------- ### Display Image with Predefined Annotations Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/README.md Load an image annotator component with an initial image and a set of predefined bounding boxes. This is useful for displaying existing annotations or for pre-populating the annotator. ```python from gradio_image_annotation import image_annotator import gradio as gr example = { "image": "https://example.com/photo.jpg", "boxes": [ {"xmin": 100, "ymin": 50, "xmax": 300, "ymax": 200, "label": "Person", "color": (0, 255, 0)} ] } with gr.Blocks() as demo: annotator = image_annotator(value=example) ``` -------------------------------- ### Import Gradio Dropdown Components Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/frontend/shared/patched_dropdown/README.md Imports necessary base components from the @gradio/dropdown package. ```html ``` -------------------------------- ### Clear Error Messages for Annotation Validation in Python Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md Provide specific and actionable error messages to guide users in correcting annotation issues. This function returns clear messages for common validation failures. ```python def validate(annotations): if not annotations: return "Error: Please upload an image first" if not annotations["boxes"]: return "Error: Draw at least one bounding box" for i, box in enumerate(annotations["boxes"]): if not box.get("label"): return f"Error: Box {i+1} is missing a label" return "✓ All validation passed" ``` -------------------------------- ### ImageAnnotator Constructor Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/INDEX.md Initializes the ImageAnnotator with various configuration options. This is the primary entry point for using the annotator. ```APIDOC ## ImageAnnotator() ### Description Initializes the ImageAnnotator class. ### Parameters This constructor accepts a wide range of parameters for customization, including: - **`params`** (dict): A dictionary of configuration options. See Configuration.md for a complete list. - **`types`** (dict): Type definitions for data handling. See Types.md for details. - **`events`** (dict): Event binding configurations. See Events.md for more information. ### Usage Example ```python from gradio_image_annotator import ImageAnnotator annotator = ImageAnnotator(params={...}, types={...}, events={...}) ``` ``` -------------------------------- ### Box Constructor Signature Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Illustrates the constructor for the Box class, detailing all parameters required for initializing a bounding box, including rendering callbacks, canvas context, coordinates, and styling options. ```typescript constructor( renderCallBack: () => void, onFinishCreation: () => void, canvasWindow: WindowViewer, pointersCache: Map, canvasXmin: number, canvasYmin: number, canvasXmax: number, canvasYmax: number, label: string, xmin: number, ymin: number, xmax: number, ymax: number, color: string = "rgb(255, 255, 255)", alpha: number = 0.5, minSize: number = 25, handleSize: number = 8, thickness: number = 2, selectedThickness: number = 4, scaleFactor: number = 1, ): void ``` -------------------------------- ### Crop Tool Configuration Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/configuration.md Set up the annotator for cropping by enabling single box mode, disabling box editing, specifying image type as numpy, and showing remove/clear buttons. Sets a custom label for the tool. ```python annotator = image_annotator( single_box=True, disable_edit_boxes=True, image_type="numpy", show_remove_button=True, show_clear_button=True, label="Draw a region to crop", ) ``` -------------------------------- ### Initiate Box Resizing Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/box_class.md Begins the resizing operation for a box using a specific handle. Sets internal state to track the resizing handle and attaches event listeners. ```typescript startResize(handleIndex: number, event: MouseEvent): void ``` -------------------------------- ### Handle Invalid Configuration Parameters Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/README.md Demonstrates how to catch and handle ValueError exceptions that may occur during the initialization of the image_annotator component due to invalid parameters. It shows a fallback mechanism to initialize with default settings. ```python try: annotator = image_annotator( image_type=user_choice, label_colors=user_colors ) except ValueError as e: # Handle invalid parameter print(f"Config error: {e}") annotator = image_annotator() # Fall back to defaults ``` -------------------------------- ### WindowViewer Constructor Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/window_viewer.md Initializes a new instance of the WindowViewer class. It takes a render callback function and a map of active pointers to manage the viewport state and user interactions. ```APIDOC ## WindowViewer Constructor ### Description Initializes a new instance of the WindowViewer class. It takes a render callback function and a map of active pointers to manage the viewport state and user interactions. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Signature ```typescript constructor( renderCallBack: () => void, pointersCache: Map ): void ``` ### Parameters - **renderCallBack** (`() => void`) - Required - Callback function invoked to trigger canvas re-render after state changes. - **pointersCache** (`Map`) - Required - Map of active pointer IDs for multi-touch tracking. ### Initial State - scale: `1.0` - offsetX: `0` - offsetY: `0` - canvasWidth: `0` - canvasHeight: `0` - imageWidth: `0` - imageHeight: `0` - imageRotatedWidth: `0` - imageRotatedHeight: `0` - isDragging: `false` - startDragX: `0` - startDragY: `0` - orientation: `0` ``` -------------------------------- ### Handle Various Image Formats Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md Avoid assuming a specific image format (e.g., NumPy array). Check the type of the image input and handle different formats like PIL Images or file paths appropriately. ```python def bad_handler(annotations): # Don't assume image is numpy height = annotations["image"].shape[0] # ❌ Breaks if PIL or filepath ``` ```python def good_handler(annotations): image = annotations["image"] if isinstance(image, np.ndarray): height = image.shape[0] elif isinstance(image, PIL.Image.Image): height = image.size[1] else: # filepath height = None ``` -------------------------------- ### Color Format Conversion Pipeline Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/utility_functions.md This diagram outlines the various stages of color format conversion, from user input tuples to hex strings and finally to RGBA strings for rendering. ```text User Input: (255, 0, 0) tuple ↓ rgb2hex() ↓ "#ff0000" hex string (stored in label_colors) ↓ Frontend: "rgb(255, 0, 0)" string (from JSON) ↓ Box.color ↓ setAlpha() ↓ "rgba(255, 0, 0, 0.5)" for rendering ``` -------------------------------- ### Set Reasonable Defaults for Image Annotator Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md Configure the image annotator with sensible default values for parameters like `box_min_size`, `boxes_alpha`, `handle_size`, `box_thickness`, and `show_remove_button`. These defaults enhance usability and prevent common issues. ```python from gradio_image_annotation.image_annotator import image_annotator annotator = image_annotator( # Conservative defaults box_min_size=20, # Prevent tiny boxes boxes_alpha=0.5, # Good visibility handle_size=8, # Touch-friendly box_thickness=2, # Clear outline show_remove_button=True # Easy to fix mistakes ) ``` -------------------------------- ### Configure Labels and Colors Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/README.md Customize the appearance and behavior of the image annotator by specifying a list of labels, their colors, minimum box size, and handle size. This allows for a tailored annotation experience. ```python annotator = image_annotator( label_list=["Person", "Car", "Bicycle", "Dog"], label_colors=[ (0, 255, 0), # Green (255, 0, 0), # Red (0, 0, 255), # Blue (255, 255, 0) # Yellow ], box_min_size=20, handle_size=10 ) ``` -------------------------------- ### Mobile-Friendly Annotator Configuration Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/configuration.md Optimize the annotator for mobile devices by limiting sources to upload and clipboard, setting dimensions to 100%, and increasing handle and box sizes for touch interaction. ```python annotator = image_annotator( sources=["upload", "clipboard"], # No webcam on all mobile height="100%", width="100%", show_remove_button=True, handle_size=12, # Larger handles for touch box_thickness=3, ) ``` -------------------------------- ### Batch Image Processing with Gradio Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/patterns.md This pattern demonstrates how to handle multiple image uploads for batch processing. Note that a single annotator processes one image at a time; true batch processing requires external handling or multiple annotator instances. ```python import gradio as gr from gradio_image_annotation import image_annotator def process_batch(annotations_list): """Process multiple annotations.""" results = [] for annotations in annotations_list: if not annotations: results.append({"status": "no_image"}) else: results.append({ "box_count": len(annotations.get("boxes", [])), "has_labels": any(b.get("label") for b in annotations["boxes"]) }) return results with gr.Blocks() as demo: # Upload multiple images via gr.File file_upload = gr.File( file_count="multiple", label="Upload Images" ) # Note: This pattern requires custom handling for multiple annotators # gr.Dataframe for displaying batch results results_table = gr.Dataframe(label="Processing Results") ``` -------------------------------- ### Image Annotator Constructor Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/image_annotator.md Initializes the image_annotator component with various configuration options for image annotation. This includes parameters for bounding box appearance, label management, image handling, and component behavior. ```python def __init__( self, value: dict | None = None, *, boxes_alpha: float = 0.5, label_list: list[str] = [], label_colors: list[str] = [], box_min_size: int = 10, handle_size: int = 8, box_thickness: int = 2, box_selected_thickness: int = 4, disable_edit_boxes: bool | None = None, single_box: bool = False, height: int | str | None = None, width: int | str | None = None, image_mode: Literal["1", "L", "P", "RGB", "RGBA", "CMYK", "YCbCr", "LAB", "HSV", "I", "F"] = "RGB", sources: list[Literal["upload", "webcam", "clipboard"]] | None = ["upload", "webcam", "clipboard"], image_type: Literal["numpy", "pil", "filepath"] = "numpy", label: str | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = True, visible: bool = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, show_label: bool | None = None, show_download_button: bool = True, show_share_button: bool | None = None, show_clear_button: bool | None = True, show_remove_button: bool | None = None, handles_cursor: bool | None = True, use_default_label: bool | None = False, enable_keyboard_shortcuts: bool = True, ) -> None ``` -------------------------------- ### Read-Only Display Configuration Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/configuration.md Configure the annotator for read-only display with a download button enabled and the remove button disabled. Set `interactive` to `False`. ```python annotator = image_annotator( interactive=False, show_download_button=True, show_remove_button=False, ) ``` -------------------------------- ### Providing Label List with Label Colors Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/errors.md When specifying custom label colors, a corresponding 'label_list' must also be provided to map colors to labels correctly. ```python # ❌ Wrong - colors without labels annotator = image_annotator(label_colors=[(255, 0, 0)]) # ✓ Correct - provide both annotator = image_annotator( label_list=["Person"], label_colors=[(255, 0, 0)] ) ``` -------------------------------- ### Constructor: Invalid sources Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/errors.md Raises ValueError if the `sources` parameter contains invalid items. Ensure the list only includes 'upload', 'clipboard', 'webcam', or None. ```python annotator = image_annotator(sources=["upload", "invalid"]) ``` ```python annotator = image_annotator(sources=["upload", "webcam"]) ``` -------------------------------- ### AnnotatedImageData to User Data Conversion Source: https://github.com/edgargracia/gradio_image_annotator/blob/main/_autodocs/api-reference/annotated_image_data.md Demonstrates the conversion of `AnnotatedImageData` received from the frontend into a format suitable for user functions. This process is handled by the `preprocess` function. ```python # AnnotatedImageData from frontend received = AnnotatedImageData( image=FileData(path="/tmp/image.png", orig_name="photo.jpg"), boxes=[ {"xmin": 10, "ymin": 20, "xmax": 100, "ymax": 150, "label": "Person", "color": "rgb(255, 0, 0)", "scaleFactor": 1.0} ], orientation=0 ) # Converted to AnnotatedImageValue value = { "image": np.ndarray or PIL.Image or str, # Depends on image_type setting "boxes": [ {"xmin": 10, "ymin": 20, "xmax": 100, "ymax": 150, "label": "Person", "color": (255, 0, 0)} ], "orientation": 0 } ```