@gradio/imageeditor 0.12.13 → 0.13.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.
Files changed (130) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/Example.svelte +1 -1
  3. package/IMAGE_EDITOR_OVERVIEW.md +224 -0
  4. package/ImageEditor.stories.svelte +4 -4
  5. package/Index.svelte +35 -46
  6. package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +56 -103
  7. package/dist/Example.svelte.d.ts +1 -1
  8. package/dist/Index.svelte +29 -33
  9. package/dist/Index.svelte.d.ts +17 -16
  10. package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +47 -88
  11. package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +13 -15
  12. package/dist/shared/Anchor.svelte +311 -0
  13. package/dist/shared/Anchor.svelte.d.ts +18 -0
  14. package/dist/shared/Controls.svelte +162 -23
  15. package/dist/shared/Controls.svelte.d.ts +7 -2
  16. package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
  17. package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
  18. package/dist/shared/ImageEditor.svelte +546 -289
  19. package/dist/shared/ImageEditor.svelte.d.ts +51 -56
  20. package/dist/shared/Layers.svelte +233 -0
  21. package/dist/shared/Layers.svelte.d.ts +35 -0
  22. package/dist/shared/Resize.svelte +218 -0
  23. package/dist/shared/Resize.svelte.d.ts +29 -0
  24. package/dist/shared/SecondaryToolbar.svelte +54 -0
  25. package/dist/shared/SecondaryToolbar.svelte.d.ts +35 -0
  26. package/dist/shared/Toolbar.svelte +337 -0
  27. package/dist/shared/Toolbar.svelte.d.ts +42 -0
  28. package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
  29. package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
  30. package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
  31. package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
  32. package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
  33. package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
  34. package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
  35. package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
  36. package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
  37. package/dist/shared/brush/brush-cursor.d.ts +101 -0
  38. package/dist/shared/brush/brush-cursor.js +327 -0
  39. package/dist/shared/brush/brush-textures.d.ts +71 -0
  40. package/dist/shared/brush/brush-textures.js +404 -0
  41. package/dist/shared/brush/brush-utils.d.ts +32 -0
  42. package/dist/shared/brush/brush-utils.js +59 -0
  43. package/dist/shared/brush/brush.d.ts +152 -0
  44. package/dist/shared/brush/brush.js +396 -0
  45. package/dist/shared/brush/types.d.ts +37 -0
  46. package/dist/shared/brush/types.js +1 -0
  47. package/dist/shared/core/editor.d.ts +252 -0
  48. package/dist/shared/core/editor.js +1221 -0
  49. package/dist/shared/crop/crop.d.ts +201 -0
  50. package/dist/shared/crop/crop.js +727 -0
  51. package/dist/shared/image/image.d.ts +89 -0
  52. package/dist/shared/image/image.js +185 -0
  53. package/dist/shared/resize/resize.d.ts +270 -0
  54. package/dist/shared/resize/resize.js +1413 -0
  55. package/dist/shared/types.d.ts +12 -0
  56. package/dist/shared/utils/pixi.d.ts +16 -57
  57. package/dist/shared/utils/pixi.js +15 -113
  58. package/dist/shared/zoom/zoom.d.ts +136 -0
  59. package/dist/shared/zoom/zoom.js +548 -0
  60. package/package.json +11 -10
  61. package/shared/Anchor.svelte +384 -0
  62. package/shared/Controls.svelte +194 -27
  63. package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
  64. package/shared/ImageEditor.svelte +682 -349
  65. package/shared/Layers.svelte +249 -0
  66. package/shared/Resize.svelte +239 -0
  67. package/shared/SecondaryToolbar.svelte +61 -0
  68. package/shared/Toolbar.svelte +386 -0
  69. package/shared/brush/BRUSH_TOOL.md +134 -0
  70. package/shared/brush/BrushOptions.svelte +200 -0
  71. package/shared/{tools → brush}/BrushSize.svelte +2 -30
  72. package/shared/{tools → brush}/ColorField.svelte +3 -1
  73. package/shared/{tools → brush}/ColorPicker.svelte +86 -9
  74. package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
  75. package/shared/brush/brush-cursor.ts +408 -0
  76. package/shared/brush/brush-textures.ts +508 -0
  77. package/shared/brush/brush-utils.ts +76 -0
  78. package/shared/brush/brush.ts +506 -0
  79. package/shared/brush/types.ts +41 -0
  80. package/shared/core/EDITOR.md +182 -0
  81. package/shared/core/editor.ts +1730 -0
  82. package/shared/crop/CROP.md +139 -0
  83. package/shared/crop/crop.ts +1027 -0
  84. package/shared/image/IMAGE.md +135 -0
  85. package/shared/image/image.ts +300 -0
  86. package/shared/resize/resize.ts +1894 -0
  87. package/shared/types.ts +14 -0
  88. package/shared/utils/pixi.ts +19 -246
  89. package/shared/zoom/zoom.ts +729 -0
  90. package/dist/shared/layers/Layers.svelte +0 -231
  91. package/dist/shared/layers/Layers.svelte.d.ts +0 -18
  92. package/dist/shared/layers/utils.d.ts +0 -73
  93. package/dist/shared/layers/utils.js +0 -156
  94. package/dist/shared/tools/Brush.svelte +0 -215
  95. package/dist/shared/tools/Brush.svelte.d.ts +0 -29
  96. package/dist/shared/tools/Crop.svelte +0 -155
  97. package/dist/shared/tools/Crop.svelte.d.ts +0 -16
  98. package/dist/shared/tools/Cropper.svelte +0 -271
  99. package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
  100. package/dist/shared/tools/Handle.svelte +0 -260
  101. package/dist/shared/tools/Handle.svelte.d.ts +0 -29
  102. package/dist/shared/tools/Sources.svelte +0 -257
  103. package/dist/shared/tools/Sources.svelte.d.ts +0 -34
  104. package/dist/shared/tools/Tools.svelte +0 -102
  105. package/dist/shared/tools/Tools.svelte.d.ts +0 -48
  106. package/dist/shared/tools/brush.d.ts +0 -62
  107. package/dist/shared/tools/brush.js +0 -133
  108. package/dist/shared/tools/crop.d.ts +0 -15
  109. package/dist/shared/tools/crop.js +0 -154
  110. package/dist/shared/tools/index.d.ts +0 -5
  111. package/dist/shared/tools/index.js +0 -5
  112. package/dist/shared/tools/sources.d.ts +0 -46
  113. package/dist/shared/tools/sources.js +0 -121
  114. package/dist/shared/tools/types.d.ts +0 -1
  115. package/shared/layers/Layers.svelte +0 -250
  116. package/shared/layers/utils.ts +0 -294
  117. package/shared/tools/Brush.svelte +0 -280
  118. package/shared/tools/BrushOptions.svelte +0 -180
  119. package/shared/tools/Crop.svelte +0 -189
  120. package/shared/tools/Cropper.svelte +0 -346
  121. package/shared/tools/Handle.svelte +0 -289
  122. package/shared/tools/Sources.svelte +0 -283
  123. package/shared/tools/Tools.svelte +0 -162
  124. package/shared/tools/brush.ts +0 -247
  125. package/shared/tools/crop.ts +0 -213
  126. package/shared/tools/index.ts +0 -5
  127. package/shared/tools/sources.ts +0 -195
  128. package/shared/tools/types.ts +0 -1
  129. /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
  130. /package/dist/shared/{tools/types.js → types.js} +0 -0
@@ -0,0 +1,14 @@
1
+ export interface ImageBlobs {
2
+ background: Blob | null;
3
+ layers: (Blob | null)[];
4
+ composite: Blob | null;
5
+ }
6
+
7
+ export interface LayerOptions {
8
+ allow_additional_layers: boolean;
9
+ layers: string[];
10
+ disabled: boolean;
11
+ }
12
+
13
+ export type Source = "upload" | "webcam" | "clipboard";
14
+ export type Transform = "crop" | "resize";
@@ -1,211 +1,4 @@
1
- import {
2
- Application,
3
- Container,
4
- Graphics,
5
- Sprite,
6
- Rectangle,
7
- RenderTexture,
8
- type IRenderer,
9
- type DisplayObject,
10
- type ICanvas
11
- } from "pixi.js";
12
-
13
- import { type LayerScene } from "../layers/utils";
14
-
15
- /**
16
- * interface holding references to pixi app components
17
- */
18
- export interface PixiApp {
19
- /**
20
- * The pixi container for layers
21
- */
22
- layer_container: Container;
23
- /**
24
- * The pixi container for background images and colors
25
- */
26
- background_container: Container;
27
- /**
28
- * The pixi renderer
29
- */
30
- renderer: IRenderer;
31
- /**
32
- * The pixi canvas
33
- */
34
- view: HTMLCanvasElement & ICanvas;
35
- /**
36
- * The pixi container for masking
37
- */
38
- mask_container: Container;
39
- destroy(): void;
40
- /**
41
- * Resizes the pixi app
42
- * @param width the new width
43
- * @param height the new height
44
- */
45
- resize(width: number, height: number): void;
46
- /**
47
- * Gets the blobs for the background, layers, and composite
48
- * @param bounds the bounds of the canvas
49
- * @returns a promise with the blobs
50
- */
51
- get_blobs(
52
- layers: LayerScene[],
53
- bounds: Rectangle,
54
- dimensions: [number, number]
55
- ): Promise<ImageBlobs>;
56
- // /**
57
- // * Resets the mask
58
- // */
59
- // reset?: () => void;
60
-
61
- /**
62
- * Gets the layers
63
- */
64
- get_layers?: () => LayerScene[];
65
- }
66
-
67
- /**
68
- * Creates a PIXI app and attaches it to a DOM element
69
- * @param target DOM element to attach PIXI app to
70
- * @param width Width of the PIXI app
71
- * @param height Height of the PIXI app
72
- * @param antialias Whether to use antialiasing
73
- * @returns object with pixi container and renderer
74
- */
75
- export function create_pixi_app({
76
- target,
77
- dimensions: [width, height],
78
- antialias
79
- }: {
80
- target: HTMLElement;
81
- dimensions: [number, number];
82
- antialias: boolean;
83
- }): PixiApp {
84
- const ratio = window.devicePixelRatio || 1;
85
- const app = new Application({
86
- width,
87
- height,
88
- antialias: antialias,
89
- backgroundAlpha: 0,
90
- eventMode: "static"
91
- });
92
- const view = app.view as HTMLCanvasElement;
93
- // ensure that we can sort the background and layer containers
94
- app.stage.sortableChildren = true;
95
- view.style.maxWidth = `${width / ratio}px`;
96
- view.style.maxHeight = `${height / ratio}px`;
97
- view.style.width = "100%";
98
- view.style.height = "100%";
99
-
100
- target.appendChild(app.view as HTMLCanvasElement);
101
-
102
- // we need a separate container for the background so that we can
103
- // clear its content without knowing too much about its children
104
- const background_container = new Container() as Container & DisplayObject;
105
- background_container.zIndex = 0;
106
- const layer_container = new Container() as Container & DisplayObject;
107
- layer_container.zIndex = 1;
108
-
109
- // ensure we can reorder layers via zIndex
110
- layer_container.sortableChildren = true;
111
-
112
- const mask_container = new Container() as Container & DisplayObject;
113
- mask_container.zIndex = 1;
114
- const composite_container = new Container() as Container & DisplayObject;
115
- composite_container.zIndex = 0;
116
-
117
- mask_container.addChild(background_container);
118
- mask_container.addChild(layer_container);
119
-
120
- app.stage.addChild(mask_container);
121
- app.stage.addChild(composite_container);
122
- const mask = new Graphics();
123
- let text = RenderTexture.create({
124
- width,
125
- height
126
- });
127
- const sprite = new Sprite(text);
128
-
129
- mask_container.mask = sprite;
130
-
131
- app.render();
132
-
133
- function reset_mask(width: number, height: number): void {
134
- background_container.removeChildren();
135
- mask.beginFill(0xffffff, 1);
136
- mask.drawRect(0, 0, width, height);
137
- mask.endFill();
138
- text = RenderTexture.create({
139
- width,
140
- height
141
- });
142
- app.renderer.render(mask, {
143
- renderTexture: text
144
- });
145
-
146
- const sprite = new Sprite(text);
147
-
148
- mask_container.mask = sprite;
149
- }
150
-
151
- function resize(width: number, height: number): void {
152
- app.renderer.resize(width, height);
153
- view.style.maxWidth = `${width / ratio}px`;
154
- view.style.maxHeight = `${height / ratio}px`;
155
- reset_mask(width, height);
156
- }
157
-
158
- async function get_blobs(
159
- _layers: LayerScene[],
160
- bounds: Rectangle,
161
- [w, h]: [number, number]
162
- ): Promise<ImageBlobs> {
163
- const background = await get_canvas_blob(
164
- app.renderer,
165
- background_container,
166
- bounds,
167
- w,
168
- h
169
- );
170
-
171
- const layers = await Promise.all(
172
- _layers.map((layer) =>
173
- get_canvas_blob(
174
- app.renderer,
175
- layer.composite as DisplayObject,
176
- bounds,
177
- w,
178
- h
179
- )
180
- )
181
- );
182
-
183
- const composite = await get_canvas_blob(
184
- app.renderer,
185
- mask_container,
186
- bounds,
187
- w,
188
- h
189
- );
190
-
191
- return {
192
- background,
193
- layers,
194
- composite
195
- };
196
- }
197
-
198
- return {
199
- layer_container,
200
- renderer: app.renderer,
201
- destroy: () => app.destroy(true),
202
- view: app.view as HTMLCanvasElement & ICanvas,
203
- background_container,
204
- mask_container,
205
- resize,
206
- get_blobs
207
- };
208
- }
1
+ import { Graphics, Rectangle, type Renderer, type Container } from "pixi.js";
209
2
 
210
3
  /**
211
4
  * Creates a pixi graphics object.
@@ -232,7 +25,7 @@ export function clamp(n: number, min: number, max: number): number {
232
25
  }
233
26
 
234
27
  /**
235
- * Generates a blob from a pixi object.
28
+ * Generates a blob from a pixi object.s
236
29
  * @param renderer The pixi renderer.
237
30
  * @param obj The pixi object to generate a blob from.
238
31
  * @param bounds The bounds of the canvas that we wish to extract
@@ -240,49 +33,29 @@ export function clamp(n: number, min: number, max: number): number {
240
33
  * @param height The full height of the canvas
241
34
  * @returns A promise with the blob.
242
35
  */
243
- function get_canvas_blob(
244
- renderer: IRenderer,
245
- obj: DisplayObject,
246
- bounds: Rectangle,
247
- width: number,
248
- height: number
36
+ export function get_canvas_blob(
37
+ renderer: Renderer,
38
+ obj: Container | null,
39
+ bounds?: { x: number; y: number; width: number; height: number }
249
40
  ): Promise<Blob | null> {
250
41
  return new Promise((resolve) => {
251
- // for some reason pixi won't extract a cropped canvas without distorting it
252
- // so we have to extract the whole canvas and crop it manually
253
- const src_canvas = renderer.extract.canvas(
254
- obj,
255
- new Rectangle(0, 0, width, height)
256
- );
257
-
258
- // Create a new canvas for the cropped area with the appropriate size
259
- let dest_canvas = document.createElement("canvas");
260
- dest_canvas.width = bounds.width;
261
- dest_canvas.height = bounds.height;
262
- let dest_ctx = dest_canvas.getContext("2d");
263
-
264
- if (!dest_ctx) {
42
+ if (!obj) {
265
43
  resolve(null);
266
- throw new Error("Could not create canvas context");
44
+ return;
267
45
  }
268
46
 
269
- // Draw the cropped area onto the destination canvas
270
- dest_ctx.drawImage(
271
- src_canvas as HTMLCanvasElement,
272
- // this is the area of the source that we want to copy (the crop box)
273
- bounds.x,
274
- bounds.y,
275
- bounds.width,
276
- bounds.height,
277
- // this is where we want to draw the crop box on the destination canvas
278
- 0,
279
- 0,
280
- bounds.width,
281
- bounds.height
282
- );
47
+ const image_bounds = obj.getLocalBounds();
48
+ const frame = bounds
49
+ ? new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height)
50
+ : new Rectangle(0, 0, image_bounds.width, image_bounds.height);
51
+
52
+ const src_canvas = renderer.extract.canvas({
53
+ target: obj,
54
+ resolution: 1,
55
+ frame
56
+ });
283
57
 
284
- // we grab a blob here so we can upload it
285
- dest_canvas.toBlob?.((blob) => {
58
+ src_canvas.toBlob?.((blob) => {
286
59
  if (!blob) {
287
60
  resolve(null);
288
61
  }