@gradio/imageeditor 0.12.14 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/Example.svelte +1 -1
- package/IMAGE_EDITOR_OVERVIEW.md +224 -0
- package/ImageEditor.stories.svelte +13 -5
- package/Index.svelte +46 -45
- package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +65 -103
- package/README.md +2 -0
- package/dist/Example.svelte.d.ts +1 -1
- package/dist/Index.svelte +35 -33
- package/dist/Index.svelte.d.ts +25 -16
- package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +54 -88
- package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +17 -15
- package/dist/shared/Anchor.svelte +311 -0
- package/dist/shared/Anchor.svelte.d.ts +18 -0
- package/dist/shared/Controls.svelte +169 -18
- package/dist/shared/Controls.svelte.d.ts +9 -2
- package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
- package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
- package/dist/shared/ImageEditor.svelte +572 -289
- package/dist/shared/ImageEditor.svelte.d.ts +54 -56
- package/dist/shared/Layers.svelte +260 -0
- package/dist/shared/Layers.svelte.d.ts +37 -0
- package/dist/shared/Resize.svelte +218 -0
- package/dist/shared/Resize.svelte.d.ts +29 -0
- package/dist/shared/SecondaryToolbar.svelte +55 -0
- package/dist/shared/SecondaryToolbar.svelte.d.ts +37 -0
- package/dist/shared/Toolbar.svelte +337 -0
- package/dist/shared/Toolbar.svelte.d.ts +42 -0
- package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
- package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
- package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
- package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
- package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
- package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
- package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
- package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
- package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
- package/dist/shared/brush/brush-cursor.d.ts +101 -0
- package/dist/shared/brush/brush-cursor.js +327 -0
- package/dist/shared/brush/brush-textures.d.ts +65 -0
- package/dist/shared/brush/brush-textures.js +385 -0
- package/dist/shared/brush/brush-utils.d.ts +32 -0
- package/dist/shared/brush/brush-utils.js +59 -0
- package/dist/shared/brush/brush.d.ts +152 -0
- package/dist/shared/brush/brush.js +397 -0
- package/dist/shared/brush/types.d.ts +37 -0
- package/dist/shared/brush/types.js +1 -0
- package/dist/shared/core/editor.d.ts +261 -0
- package/dist/shared/core/editor.js +1264 -0
- package/dist/shared/crop/crop.d.ts +201 -0
- package/dist/shared/crop/crop.js +727 -0
- package/dist/shared/image/image.d.ts +89 -0
- package/dist/shared/image/image.js +183 -0
- package/dist/shared/resize/resize.d.ts +270 -0
- package/dist/shared/resize/resize.js +1413 -0
- package/dist/shared/types.d.ts +16 -0
- package/dist/shared/utils/pixi.d.ts +16 -57
- package/dist/shared/utils/pixi.js +15 -113
- package/dist/shared/zoom/zoom.d.ts +136 -0
- package/dist/shared/zoom/zoom.js +548 -0
- package/package.json +8 -7
- package/shared/Anchor.svelte +384 -0
- package/shared/Controls.svelte +178 -37
- package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
- package/shared/ImageEditor.svelte +712 -350
- package/shared/Layers.svelte +282 -0
- package/shared/Resize.svelte +239 -0
- package/shared/SecondaryToolbar.svelte +67 -0
- package/shared/Toolbar.svelte +386 -0
- package/shared/brush/BRUSH_TOOL.md +134 -0
- package/shared/brush/BrushOptions.svelte +200 -0
- package/shared/{tools → brush}/BrushSize.svelte +2 -30
- package/shared/{tools → brush}/ColorField.svelte +3 -1
- package/shared/{tools → brush}/ColorPicker.svelte +86 -9
- package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
- package/shared/brush/brush-cursor.ts +408 -0
- package/shared/brush/brush-textures.ts +485 -0
- package/shared/brush/brush-utils.ts +76 -0
- package/shared/brush/brush.ts +510 -0
- package/shared/brush/types.ts +41 -0
- package/shared/core/EDITOR.md +182 -0
- package/shared/core/editor.ts +1788 -0
- package/shared/crop/CROP.md +139 -0
- package/shared/crop/crop.ts +1027 -0
- package/shared/image/IMAGE.md +135 -0
- package/shared/image/image.ts +298 -0
- package/shared/resize/resize.ts +1894 -0
- package/shared/types.ts +19 -0
- package/shared/utils/pixi.ts +19 -246
- package/shared/zoom/zoom.ts +729 -0
- package/dist/shared/layers/Layers.svelte +0 -231
- package/dist/shared/layers/Layers.svelte.d.ts +0 -18
- package/dist/shared/layers/utils.d.ts +0 -73
- package/dist/shared/layers/utils.js +0 -156
- package/dist/shared/tools/Brush.svelte +0 -215
- package/dist/shared/tools/Brush.svelte.d.ts +0 -29
- package/dist/shared/tools/Crop.svelte +0 -155
- package/dist/shared/tools/Crop.svelte.d.ts +0 -16
- package/dist/shared/tools/Cropper.svelte +0 -271
- package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
- package/dist/shared/tools/Handle.svelte +0 -260
- package/dist/shared/tools/Handle.svelte.d.ts +0 -29
- package/dist/shared/tools/Sources.svelte +0 -257
- package/dist/shared/tools/Sources.svelte.d.ts +0 -34
- package/dist/shared/tools/Tools.svelte +0 -102
- package/dist/shared/tools/Tools.svelte.d.ts +0 -48
- package/dist/shared/tools/brush.d.ts +0 -62
- package/dist/shared/tools/brush.js +0 -133
- package/dist/shared/tools/crop.d.ts +0 -15
- package/dist/shared/tools/crop.js +0 -154
- package/dist/shared/tools/index.d.ts +0 -5
- package/dist/shared/tools/index.js +0 -5
- package/dist/shared/tools/sources.d.ts +0 -46
- package/dist/shared/tools/sources.js +0 -121
- package/dist/shared/tools/types.d.ts +0 -1
- package/shared/layers/Layers.svelte +0 -250
- package/shared/layers/utils.ts +0 -294
- package/shared/tools/Brush.svelte +0 -280
- package/shared/tools/BrushOptions.svelte +0 -180
- package/shared/tools/Crop.svelte +0 -189
- package/shared/tools/Cropper.svelte +0 -346
- package/shared/tools/Handle.svelte +0 -289
- package/shared/tools/Sources.svelte +0 -283
- package/shared/tools/Tools.svelte +0 -162
- package/shared/tools/brush.ts +0 -247
- package/shared/tools/crop.ts +0 -213
- package/shared/tools/index.ts +0 -5
- package/shared/tools/sources.ts +0 -195
- package/shared/tools/types.ts +0 -1
- /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
- /package/dist/shared/{tools/types.js → types.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @gradio/imageeditor
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#10981](https://github.com/gradio-app/gradio/pull/10981) [`0db230f`](https://github.com/gradio-app/gradio/commit/0db230f5c2f19d9b3b455adb1b30ed9374ae1791) - allow users to change the visibility of layers in the image editor. Thanks @pngwn!
|
|
8
|
+
|
|
9
|
+
### Fixes
|
|
10
|
+
|
|
11
|
+
- [#10999](https://github.com/gradio-app/gradio/pull/10999) [`8c70819`](https://github.com/gradio-app/gradio/commit/8c70819f87027b75e44f49a13050ae2c3e8b3580) - implement download button for the ImageEditor. Thanks @pngwn!
|
|
12
|
+
- [#10997](https://github.com/gradio-app/gradio/pull/10997) [`45d5840`](https://github.com/gradio-app/gradio/commit/45d5840fb265328f3aa0c050ce9c6b87ae7dbbc5) - When custom layers are provided to the ImageEditor, always default to the first layer. Thanks @pngwn!
|
|
13
|
+
- [#10979](https://github.com/gradio-app/gradio/pull/10979) [`975feee`](https://github.com/gradio-app/gradio/commit/975feee3925e5b65e52ae00da5c5066d8889ae6a) - improve webcam options for the ImageEditor. Thanks @pngwn!
|
|
14
|
+
- [#10995](https://github.com/gradio-app/gradio/pull/10995) [`fc59815`](https://github.com/gradio-app/gradio/commit/fc598151aa9c77a84f6e7eaf9bcc0cae6ba49369) - ensure the image editor background respects the theme mode. Thanks @pngwn!
|
|
15
|
+
- [#10994](https://github.com/gradio-app/gradio/pull/10994) [`714015a`](https://github.com/gradio-app/gradio/commit/714015a1868168721ae79d6b5bc10fbc5bbb4290) - ensure images uploaded to the ImageEditor correctly initialise the canvas dimensions. Thanks @pngwn!
|
|
16
|
+
|
|
17
|
+
### Dependency updates
|
|
18
|
+
|
|
19
|
+
- @gradio/upload@0.16.1
|
|
20
|
+
- @gradio/atoms@0.15.1
|
|
21
|
+
- @gradio/statustracker@0.10.8
|
|
22
|
+
- @gradio/icons@0.12.0
|
|
23
|
+
- @gradio/image@0.22.1
|
|
24
|
+
|
|
25
|
+
## 0.13.0
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
- [#10635](https://github.com/gradio-app/gradio/pull/10635) [`2f68c9d`](https://github.com/gradio-app/gradio/commit/2f68c9d988dcbc53a0b8e53bdb1de49c9c8c65d8) - Refactor and redesign `ImageEditor` component. Thanks @pngwn!
|
|
30
|
+
|
|
31
|
+
### Dependency updates
|
|
32
|
+
|
|
33
|
+
- @gradio/statustracker@0.10.7
|
|
34
|
+
- @gradio/atoms@0.15.0
|
|
35
|
+
- @gradio/icons@0.11.0
|
|
36
|
+
- @gradio/upload@0.16.0
|
|
37
|
+
- @gradio/image@0.22.0
|
|
38
|
+
|
|
3
39
|
## 0.12.14
|
|
4
40
|
|
|
5
41
|
### Dependency updates
|
package/Example.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { BaseImage as Image } from "@gradio/image";
|
|
3
|
-
import type { EditorData } from "./
|
|
3
|
+
import type { EditorData } from "./InteractiveImageEditor.svelte";
|
|
4
4
|
|
|
5
5
|
export let value: EditorData;
|
|
6
6
|
export let type: "gallery" | "table";
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Image Editor Overview
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
The Image Editor is a powerful, web-based tool built with PIXI.js and Svelte that allows users to edit images through a variety of operations including drawing, erasing, cropping, and resizing. It features a layered architecture, undo/redo functionality, and a modular tool system. This document provides a high-level overview of the editor's architecture and components to help developers understand the system before diving into specific implementations.
|
|
6
|
+
|
|
7
|
+
## Architecture Overview
|
|
8
|
+
|
|
9
|
+
The image editor follows a modular architecture with several key components:
|
|
10
|
+
|
|
11
|
+
1. **Core Editor** - The central component that manages the canvas, tools, layers, and user interactions
|
|
12
|
+
2. **Tool System** - A pluggable system for different editing operations (crop, draw, erase, etc.)
|
|
13
|
+
3. **Layer Management** - Handles multiple layers for complex image compositions
|
|
14
|
+
4. **Command Pattern** - Implements undo/redo functionality through commands
|
|
15
|
+
5. **UI Components** - Svelte components that provide the user interface
|
|
16
|
+
6. **Rendering Pipeline** - PIXI.js-based rendering system for the canvas
|
|
17
|
+
|
|
18
|
+
### Component Hierarchy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
InteractiveImageEditor.svelte
|
|
22
|
+
└── ImageEditor.svelte
|
|
23
|
+
├── Core Editor (editor.ts)
|
|
24
|
+
│ ├── Command Manager
|
|
25
|
+
│ └── Layer Manager
|
|
26
|
+
├── Tools
|
|
27
|
+
│ ├── Image Tool (image.ts)
|
|
28
|
+
│ ├── Crop Tool (crop.ts)
|
|
29
|
+
│ ├── Brush Tool (brush.ts)
|
|
30
|
+
│ ├── Resize Tool (resize.ts)
|
|
31
|
+
│ └── Zoom Tool (zoom.ts)
|
|
32
|
+
└── UI Components
|
|
33
|
+
├── Toolbar.svelte
|
|
34
|
+
├── Controls.svelte
|
|
35
|
+
└── Tool-specific UI components
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Key Components
|
|
39
|
+
|
|
40
|
+
### Core Editor
|
|
41
|
+
|
|
42
|
+
The Core Editor (`editor.ts`) is the central component that initializes and manages the editor. It:
|
|
43
|
+
|
|
44
|
+
- Sets up the PIXI.js application and containers
|
|
45
|
+
- Manages tools and handles tool switching
|
|
46
|
+
- Maintains the editor state (scale, position, dimensions)
|
|
47
|
+
- Executes commands and manages undo/redo
|
|
48
|
+
- Handles the rendering loop
|
|
49
|
+
|
|
50
|
+
The editor uses Svelte stores for reactive state management and springs for smooth animations.
|
|
51
|
+
|
|
52
|
+
### Tool System
|
|
53
|
+
|
|
54
|
+
The editor implements a pluggable tool system where each tool follows the `Tool` interface:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
interface Tool {
|
|
58
|
+
name: string;
|
|
59
|
+
setup(context: ImageEditorContext, tool: ToolbarTool, subtool: Subtool): Promise<void>;
|
|
60
|
+
cleanup(): void;
|
|
61
|
+
set_tool(tool: ToolbarTool, subtool: Subtool): void;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Each tool receives the editor context during setup, which provides access to the PIXI.js application, containers, and other utilities. Tools are responsible for handling their specific functionality and cleaning up resources when deactivated.
|
|
66
|
+
|
|
67
|
+
#### Available Tools
|
|
68
|
+
|
|
69
|
+
1. **Image Tool** - Handles adding and managing background images
|
|
70
|
+
2. **Crop Tool** - Allows selecting a portion of the image to keep
|
|
71
|
+
3. **Brush Tool** - Provides drawing functionality with customizable brushes
|
|
72
|
+
4. **Erase Tool** - Allows erasing parts of the image
|
|
73
|
+
5. **Resize Tool** - Enables resizing the canvas
|
|
74
|
+
6. **Zoom Tool** - Handles zooming and panning the canvas
|
|
75
|
+
|
|
76
|
+
### Layer Management
|
|
77
|
+
|
|
78
|
+
The editor supports a layered approach to image editing:
|
|
79
|
+
|
|
80
|
+
- **Background Layer** - Contains the background image
|
|
81
|
+
- **Drawing Layers** - Contains user drawings and modifications
|
|
82
|
+
- **UI Layer** - Contains UI elements that overlay the canvas
|
|
83
|
+
|
|
84
|
+
Each layer has associated textures for rendering and can be manipulated independently.
|
|
85
|
+
|
|
86
|
+
### Command Pattern
|
|
87
|
+
|
|
88
|
+
The editor implements the Command pattern for undo/redo functionality:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
interface Command {
|
|
92
|
+
execute(): void;
|
|
93
|
+
undo(): void;
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Operations that modify the canvas state (like adding an image, drawing, or cropping) are implemented as commands. This allows for complex operations to be encapsulated and reversed.
|
|
98
|
+
|
|
99
|
+
### UI Components
|
|
100
|
+
|
|
101
|
+
The UI is built with Svelte components:
|
|
102
|
+
|
|
103
|
+
- **ImageEditor.svelte** - The main editor component
|
|
104
|
+
- **Toolbar.svelte** - Provides tool selection
|
|
105
|
+
- **Controls.svelte** - Provides additional controls (save, undo, redo)
|
|
106
|
+
- **Tool-specific components** - Provide UI for specific tools (BrushOptions, ColorPicker, etc.)
|
|
107
|
+
|
|
108
|
+
### Rendering Pipeline
|
|
109
|
+
|
|
110
|
+
The editor uses PIXI.js for rendering:
|
|
111
|
+
|
|
112
|
+
1. **Layer Rendering** - Each layer renders its content to a texture
|
|
113
|
+
2. **Container Composition** - Layers are composed in the image container
|
|
114
|
+
3. **UI Overlay** - UI elements are rendered on top of the image
|
|
115
|
+
4. **Scale and Position** - The image container is scaled and positioned based on user interactions
|
|
116
|
+
|
|
117
|
+
## Data Flow
|
|
118
|
+
|
|
119
|
+
1. **User Interaction** - User interacts with the UI or canvas
|
|
120
|
+
2. **Tool Handling** - The active tool handles the interaction
|
|
121
|
+
3. **Command Creation** - A command is created for operations that modify the canvas
|
|
122
|
+
4. **Command Execution** - The command is executed and registered with the command manager
|
|
123
|
+
5. **State Update** - The editor state is updated
|
|
124
|
+
6. **Rendering** - The canvas is re-rendered to reflect the changes
|
|
125
|
+
|
|
126
|
+
## Integration Points
|
|
127
|
+
|
|
128
|
+
### Svelte Integration
|
|
129
|
+
|
|
130
|
+
The editor is designed to work with Svelte:
|
|
131
|
+
|
|
132
|
+
- **Stores** - Uses Svelte stores for reactive state management
|
|
133
|
+
- **Springs** - Uses Svelte springs for smooth animations
|
|
134
|
+
- **Component Integration** - Can be integrated with Svelte components
|
|
135
|
+
|
|
136
|
+
### External Integration
|
|
137
|
+
|
|
138
|
+
The editor can be integrated with external systems:
|
|
139
|
+
|
|
140
|
+
- **File Upload** - Supports uploading images from various sources
|
|
141
|
+
- **Export** - Can export the edited image in various formats
|
|
142
|
+
- **History** - Can save and restore editing history
|
|
143
|
+
|
|
144
|
+
## Design Considerations
|
|
145
|
+
|
|
146
|
+
### Performance
|
|
147
|
+
|
|
148
|
+
The editor uses several techniques to maintain performance:
|
|
149
|
+
|
|
150
|
+
- **Texture Management** - Efficiently manages textures to minimize memory usage
|
|
151
|
+
- **Layer Composition** - Composes layers efficiently to minimize rendering overhead
|
|
152
|
+
- **Event Throttling** - Throttles events to avoid excessive updates
|
|
153
|
+
- **Resolution Scaling** - Adjusts resolution based on device pixel ratio
|
|
154
|
+
|
|
155
|
+
### Extensibility
|
|
156
|
+
|
|
157
|
+
The editor is designed to be extensible:
|
|
158
|
+
|
|
159
|
+
- **Tool Interface** - New tools can be added by implementing the Tool interface
|
|
160
|
+
- **Command Pattern** - New operations can be added by implementing the Command interface
|
|
161
|
+
- **Layer System** - The layer system can be extended to support new layer types
|
|
162
|
+
|
|
163
|
+
### Usability
|
|
164
|
+
|
|
165
|
+
The editor prioritizes usability:
|
|
166
|
+
|
|
167
|
+
- **Responsive UI** - The UI adapts to different screen sizes
|
|
168
|
+
- **Smooth Animations** - Uses springs for smooth transitions
|
|
169
|
+
- **Intuitive Controls** - Provides familiar controls for common operations
|
|
170
|
+
- **Visual Feedback** - Provides visual feedback for user actions
|
|
171
|
+
|
|
172
|
+
## Implementation Notes
|
|
173
|
+
|
|
174
|
+
When working with the image editor, consider the following:
|
|
175
|
+
|
|
176
|
+
1. **Resource Management** - Always clean up resources (textures, sprites, event listeners) to prevent memory leaks
|
|
177
|
+
2. **Event Handling** - Be careful with event propagation and stopping
|
|
178
|
+
3. **Coordinate Systems** - Be aware of the different coordinate systems (global, local, scaled)
|
|
179
|
+
4. **State Management** - Update state through the appropriate methods to ensure proper notification
|
|
180
|
+
5. **Command Pattern** - Use the Command pattern for operations that should be undoable
|
|
181
|
+
|
|
182
|
+
## Tool-Specific Considerations
|
|
183
|
+
|
|
184
|
+
### Image Tool
|
|
185
|
+
|
|
186
|
+
- Handles adding images to the canvas
|
|
187
|
+
- Manages image dimensions and positioning
|
|
188
|
+
- Integrates with the layer system
|
|
189
|
+
- Supports fixed canvas mode and flexible canvas mode
|
|
190
|
+
|
|
191
|
+
### Crop Tool
|
|
192
|
+
|
|
193
|
+
- Provides an interactive crop area with draggable handles
|
|
194
|
+
- Uses a mask to show only the selected area
|
|
195
|
+
- Handles scaling and coordinate conversions
|
|
196
|
+
- Enforces constraints on the crop area
|
|
197
|
+
|
|
198
|
+
### Brush Tool
|
|
199
|
+
|
|
200
|
+
- Supports drawing and erasing
|
|
201
|
+
- Provides customizable brush settings (size, color, opacity)
|
|
202
|
+
- Uses point interpolation for smooth lines
|
|
203
|
+
- Shows a preview of the brush before drawing
|
|
204
|
+
|
|
205
|
+
### Resize Tool
|
|
206
|
+
|
|
207
|
+
- Allows resizing the canvas
|
|
208
|
+
- Preserves content when resizing
|
|
209
|
+
- Handles aspect ratio constraints
|
|
210
|
+
- Updates the editor state after resizing
|
|
211
|
+
|
|
212
|
+
## Future Improvements
|
|
213
|
+
|
|
214
|
+
Potential areas for enhancement:
|
|
215
|
+
|
|
216
|
+
1. **Performance Optimization** - Further optimize rendering for large canvases
|
|
217
|
+
2. **Tool Extensions** - Add support for more tools and tool options
|
|
218
|
+
3. **Layer Effects** - Add support for layer effects and blending modes
|
|
219
|
+
4. **Selection Tools** - Enhance selection tools and operations
|
|
220
|
+
5. **Export Options** - Add more export options and formats
|
|
221
|
+
|
|
222
|
+
## Conclusion
|
|
223
|
+
|
|
224
|
+
The Image Editor is a powerful, extensible system for image editing. Its modular architecture, command pattern implementation, and layer management system provide a solid foundation for a wide range of image editing operations. By understanding the high-level architecture and components, developers can more easily navigate and extend the codebase.
|
|
@@ -51,11 +51,15 @@
|
|
|
51
51
|
},
|
|
52
52
|
eraser: {
|
|
53
53
|
default_size: "auto"
|
|
54
|
+
},
|
|
55
|
+
webcam_options: {
|
|
56
|
+
mirror: true,
|
|
57
|
+
constraints: null
|
|
54
58
|
}
|
|
55
59
|
}}
|
|
56
60
|
/>
|
|
57
61
|
|
|
58
|
-
<Story
|
|
62
|
+
<!-- <Story
|
|
59
63
|
name="Image Editor Undo/Redo Interactions"
|
|
60
64
|
args={{
|
|
61
65
|
value: {
|
|
@@ -108,15 +112,15 @@
|
|
|
108
112
|
|
|
109
113
|
await userEvent.click(canvas.getByLabelText("Redo"));
|
|
110
114
|
}}
|
|
111
|
-
/>
|
|
115
|
+
/> -->
|
|
112
116
|
|
|
113
117
|
<Story
|
|
114
118
|
name="Static Image Display"
|
|
115
119
|
args={{
|
|
116
120
|
value: {
|
|
117
121
|
composite: {
|
|
118
|
-
path: "",
|
|
119
|
-
url: "/
|
|
122
|
+
path: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
|
123
|
+
url: "https://gradio-builds.s3.amazonaws.com/demo-files/ghepardo-primo-piano.jpg",
|
|
120
124
|
size: null,
|
|
121
125
|
orig_name: null,
|
|
122
126
|
mime_type: null,
|
|
@@ -133,6 +137,10 @@
|
|
|
133
137
|
interactive: false,
|
|
134
138
|
label: "Image Editor",
|
|
135
139
|
show_label: true,
|
|
136
|
-
canvas_size: [800, 600]
|
|
140
|
+
canvas_size: [800, 600],
|
|
141
|
+
webcam_options: {
|
|
142
|
+
mirror: true,
|
|
143
|
+
constraints: null
|
|
144
|
+
}
|
|
137
145
|
}}
|
|
138
146
|
/>
|
package/Index.svelte
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
<svelte:options accessors={true} immutable={true} />
|
|
2
2
|
|
|
3
3
|
<script lang="ts">
|
|
4
|
-
import type { Brush, Eraser } from "./shared/
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from "./shared/InteractiveImageEditor.svelte";
|
|
4
|
+
import type { Brush, Eraser } from "./shared/brush/types";
|
|
5
|
+
import type { EditorData, ImageBlobs } from "./InteractiveImageEditor.svelte";
|
|
6
|
+
|
|
7
|
+
import { FileData } from "@gradio/client";
|
|
9
8
|
|
|
10
9
|
import type { Gradio, SelectData } from "@gradio/utils";
|
|
11
10
|
import { BaseStaticImage as StaticImage } from "@gradio/image";
|
|
12
|
-
import InteractiveImageEditor from "./
|
|
11
|
+
import InteractiveImageEditor from "./InteractiveImageEditor.svelte";
|
|
13
12
|
import { Block } from "@gradio/atoms";
|
|
14
13
|
import { StatusTracker } from "@gradio/statustracker";
|
|
15
14
|
import type { LoadingStatus } from "@gradio/statustracker";
|
|
16
15
|
import { tick } from "svelte";
|
|
16
|
+
import type {
|
|
17
|
+
LayerOptions,
|
|
18
|
+
Transform,
|
|
19
|
+
Source,
|
|
20
|
+
WebcamOptions
|
|
21
|
+
} from "./shared/types";
|
|
17
22
|
|
|
18
23
|
export let elem_id = "";
|
|
19
24
|
export let elem_classes: string[] = [];
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
export let root: string;
|
|
30
35
|
export let value_is_output = false;
|
|
31
36
|
|
|
32
|
-
export let height
|
|
37
|
+
export let height = 350;
|
|
33
38
|
export let width: number | undefined;
|
|
34
39
|
|
|
35
40
|
export let _selectable = false;
|
|
@@ -38,19 +43,13 @@
|
|
|
38
43
|
export let min_width: number | undefined = undefined;
|
|
39
44
|
export let loading_status: LoadingStatus;
|
|
40
45
|
export let show_share_button = false;
|
|
41
|
-
export let sources:
|
|
42
|
-
"upload",
|
|
43
|
-
"clipboard",
|
|
44
|
-
"webcam"
|
|
45
|
-
];
|
|
46
|
+
export let sources: Source[] = [];
|
|
46
47
|
export let interactive: boolean;
|
|
47
48
|
export let placeholder: string | undefined;
|
|
48
|
-
|
|
49
49
|
export let brush: Brush;
|
|
50
50
|
export let eraser: Eraser;
|
|
51
|
-
export let
|
|
52
|
-
export let
|
|
53
|
-
export let layers = true;
|
|
51
|
+
export let transforms: Transform[] = [];
|
|
52
|
+
export let layers: LayerOptions;
|
|
54
53
|
export let attached_events: string[] = [];
|
|
55
54
|
export let server: {
|
|
56
55
|
accept_blobs: (a: any) => void;
|
|
@@ -59,7 +58,6 @@
|
|
|
59
58
|
export let fixed_canvas = false;
|
|
60
59
|
export let show_fullscreen_button = true;
|
|
61
60
|
export let full_history: any = null;
|
|
62
|
-
|
|
63
61
|
export let gradio: Gradio<{
|
|
64
62
|
change: never;
|
|
65
63
|
error: string;
|
|
@@ -73,6 +71,9 @@
|
|
|
73
71
|
share: ShareData;
|
|
74
72
|
clear_status: LoadingStatus;
|
|
75
73
|
}>;
|
|
74
|
+
export let border_region = 0;
|
|
75
|
+
export let webcam_options: WebcamOptions;
|
|
76
|
+
export let theme_mode: "dark" | "light";
|
|
76
77
|
|
|
77
78
|
let editor_instance: InteractiveImageEditor;
|
|
78
79
|
let image_id: null | string = null;
|
|
@@ -89,8 +90,7 @@
|
|
|
89
90
|
return blobs;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
let
|
|
93
|
-
|
|
93
|
+
let is_dragging: boolean;
|
|
94
94
|
$: value && handle_change();
|
|
95
95
|
const is_browser = typeof window !== "undefined";
|
|
96
96
|
const raf = is_browser
|
|
@@ -126,32 +126,30 @@
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
let dynamic_height: number | undefined = undefined;
|
|
130
|
-
|
|
131
|
-
// In case no height given, pick a height large enough for the entire canvas
|
|
132
|
-
// in pixi.ts, the max-height of the canvas is canvas height / pixel ratio
|
|
133
|
-
|
|
134
|
-
let safe_height_initial = Math.max(
|
|
135
|
-
canvas_size[1] / (is_browser ? window.devicePixelRatio : 1),
|
|
136
|
-
250
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
$: safe_height = Math.max((dynamic_height ?? safe_height_initial) + 100, 250);
|
|
140
|
-
|
|
141
129
|
$: has_value = value?.background || value?.layers?.length || value?.composite;
|
|
130
|
+
|
|
131
|
+
$: normalised_background = value?.background
|
|
132
|
+
? new FileData(value.background)
|
|
133
|
+
: null;
|
|
134
|
+
$: normalised_composite = value?.composite
|
|
135
|
+
? new FileData(value.composite)
|
|
136
|
+
: null;
|
|
137
|
+
$: normalised_layers =
|
|
138
|
+
value?.layers?.map((layer) => new FileData(layer)) || [];
|
|
142
139
|
</script>
|
|
143
140
|
|
|
144
141
|
{#if !interactive}
|
|
145
142
|
<Block
|
|
146
143
|
{visible}
|
|
147
144
|
variant={"solid"}
|
|
148
|
-
border_mode={
|
|
145
|
+
border_mode={is_dragging ? "focus" : "base"}
|
|
149
146
|
padding={false}
|
|
150
147
|
{elem_id}
|
|
151
148
|
{elem_classes}
|
|
152
149
|
{height}
|
|
153
150
|
{width}
|
|
154
|
-
allow_overflow={
|
|
151
|
+
allow_overflow={true}
|
|
152
|
+
overflow_behavior="visible"
|
|
155
153
|
{container}
|
|
156
154
|
{scale}
|
|
157
155
|
{min_width}
|
|
@@ -180,13 +178,14 @@
|
|
|
180
178
|
<Block
|
|
181
179
|
{visible}
|
|
182
180
|
variant={has_value ? "solid" : "dashed"}
|
|
183
|
-
border_mode={
|
|
181
|
+
border_mode={is_dragging ? "focus" : "base"}
|
|
184
182
|
padding={false}
|
|
185
183
|
{elem_id}
|
|
186
184
|
{elem_classes}
|
|
187
|
-
|
|
185
|
+
{height}
|
|
188
186
|
{width}
|
|
189
|
-
allow_overflow={
|
|
187
|
+
allow_overflow={true}
|
|
188
|
+
overflow_behavior="visible"
|
|
190
189
|
{container}
|
|
191
190
|
{scale}
|
|
192
191
|
{min_width}
|
|
@@ -199,25 +198,25 @@
|
|
|
199
198
|
/>
|
|
200
199
|
|
|
201
200
|
<InteractiveImageEditor
|
|
201
|
+
{border_region}
|
|
202
202
|
on:history={(e) => (full_history = e.detail)}
|
|
203
|
-
bind:
|
|
203
|
+
bind:is_dragging
|
|
204
204
|
{canvas_size}
|
|
205
205
|
on:change={() => handle_history_change()}
|
|
206
206
|
bind:image_id
|
|
207
|
-
{
|
|
208
|
-
{
|
|
207
|
+
layers={normalised_layers}
|
|
208
|
+
composite={normalised_composite}
|
|
209
|
+
background={normalised_background}
|
|
209
210
|
bind:this={editor_instance}
|
|
210
|
-
bind:dynamic_height
|
|
211
211
|
{root}
|
|
212
212
|
{sources}
|
|
213
213
|
{label}
|
|
214
214
|
{show_label}
|
|
215
|
-
{height}
|
|
216
215
|
{fixed_canvas}
|
|
217
216
|
on:save={(e) => handle_save()}
|
|
218
217
|
on:edit={() => gradio.dispatch("edit")}
|
|
219
218
|
on:clear={() => gradio.dispatch("clear")}
|
|
220
|
-
on:drag={({ detail }) => (
|
|
219
|
+
on:drag={({ detail }) => (is_dragging = detail)}
|
|
221
220
|
on:upload={() => gradio.dispatch("upload")}
|
|
222
221
|
on:share={({ detail }) => gradio.dispatch("share", detail)}
|
|
223
222
|
on:error={({ detail }) => {
|
|
@@ -240,12 +239,14 @@
|
|
|
240
239
|
i18n={gradio.i18n}
|
|
241
240
|
{transforms}
|
|
242
241
|
accept_blobs={server.accept_blobs}
|
|
243
|
-
{layers}
|
|
244
|
-
status={loading_status?.status}
|
|
242
|
+
layer_options={layers}
|
|
245
243
|
upload={(...args) => gradio.client.upload(...args)}
|
|
246
|
-
stream_handler={(...args) => gradio.client.stream(...args)}
|
|
247
244
|
{placeholder}
|
|
248
245
|
{full_history}
|
|
246
|
+
{webcam_options}
|
|
247
|
+
{show_download_button}
|
|
248
|
+
{theme_mode}
|
|
249
|
+
on:download_error={(e) => gradio.dispatch("error", e.detail)}
|
|
249
250
|
></InteractiveImageEditor>
|
|
250
251
|
</Block>
|
|
251
252
|
{/if}
|