@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.
Files changed (131) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/Example.svelte +1 -1
  3. package/IMAGE_EDITOR_OVERVIEW.md +224 -0
  4. package/ImageEditor.stories.svelte +13 -5
  5. package/Index.svelte +46 -45
  6. package/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +65 -103
  7. package/README.md +2 -0
  8. package/dist/Example.svelte.d.ts +1 -1
  9. package/dist/Index.svelte +35 -33
  10. package/dist/Index.svelte.d.ts +25 -16
  11. package/dist/{shared/InteractiveImageEditor.svelte → InteractiveImageEditor.svelte} +54 -88
  12. package/dist/{shared/InteractiveImageEditor.svelte.d.ts → InteractiveImageEditor.svelte.d.ts} +17 -15
  13. package/dist/shared/Anchor.svelte +311 -0
  14. package/dist/shared/Anchor.svelte.d.ts +18 -0
  15. package/dist/shared/Controls.svelte +169 -18
  16. package/dist/shared/Controls.svelte.d.ts +9 -2
  17. package/dist/shared/{tools/IconButton.svelte → IconButton.svelte} +19 -3
  18. package/dist/shared/{tools/IconButton.svelte.d.ts → IconButton.svelte.d.ts} +4 -1
  19. package/dist/shared/ImageEditor.svelte +572 -289
  20. package/dist/shared/ImageEditor.svelte.d.ts +54 -56
  21. package/dist/shared/Layers.svelte +260 -0
  22. package/dist/shared/Layers.svelte.d.ts +37 -0
  23. package/dist/shared/Resize.svelte +218 -0
  24. package/dist/shared/Resize.svelte.d.ts +29 -0
  25. package/dist/shared/SecondaryToolbar.svelte +55 -0
  26. package/dist/shared/SecondaryToolbar.svelte.d.ts +37 -0
  27. package/dist/shared/Toolbar.svelte +337 -0
  28. package/dist/shared/Toolbar.svelte.d.ts +42 -0
  29. package/dist/shared/{tools → brush}/BrushOptions.svelte +68 -64
  30. package/dist/shared/{tools → brush}/BrushOptions.svelte.d.ts +9 -9
  31. package/dist/shared/{tools → brush}/BrushSize.svelte +2 -27
  32. package/dist/shared/{tools → brush}/ColorField.svelte +2 -1
  33. package/dist/shared/{tools → brush}/ColorField.svelte.d.ts +1 -0
  34. package/dist/shared/{tools → brush}/ColorPicker.svelte +81 -9
  35. package/dist/shared/{tools → brush}/ColorPicker.svelte.d.ts +1 -0
  36. package/dist/shared/{tools → brush}/ColorSwatch.svelte +78 -38
  37. package/dist/shared/{tools → brush}/ColorSwatch.svelte.d.ts +6 -2
  38. package/dist/shared/brush/brush-cursor.d.ts +101 -0
  39. package/dist/shared/brush/brush-cursor.js +327 -0
  40. package/dist/shared/brush/brush-textures.d.ts +65 -0
  41. package/dist/shared/brush/brush-textures.js +385 -0
  42. package/dist/shared/brush/brush-utils.d.ts +32 -0
  43. package/dist/shared/brush/brush-utils.js +59 -0
  44. package/dist/shared/brush/brush.d.ts +152 -0
  45. package/dist/shared/brush/brush.js +397 -0
  46. package/dist/shared/brush/types.d.ts +37 -0
  47. package/dist/shared/brush/types.js +1 -0
  48. package/dist/shared/core/editor.d.ts +261 -0
  49. package/dist/shared/core/editor.js +1264 -0
  50. package/dist/shared/crop/crop.d.ts +201 -0
  51. package/dist/shared/crop/crop.js +727 -0
  52. package/dist/shared/image/image.d.ts +89 -0
  53. package/dist/shared/image/image.js +183 -0
  54. package/dist/shared/resize/resize.d.ts +270 -0
  55. package/dist/shared/resize/resize.js +1413 -0
  56. package/dist/shared/types.d.ts +16 -0
  57. package/dist/shared/utils/pixi.d.ts +16 -57
  58. package/dist/shared/utils/pixi.js +15 -113
  59. package/dist/shared/zoom/zoom.d.ts +136 -0
  60. package/dist/shared/zoom/zoom.js +548 -0
  61. package/package.json +8 -7
  62. package/shared/Anchor.svelte +384 -0
  63. package/shared/Controls.svelte +178 -37
  64. package/shared/{tools/IconButton.svelte → IconButton.svelte} +21 -4
  65. package/shared/ImageEditor.svelte +712 -350
  66. package/shared/Layers.svelte +282 -0
  67. package/shared/Resize.svelte +239 -0
  68. package/shared/SecondaryToolbar.svelte +67 -0
  69. package/shared/Toolbar.svelte +386 -0
  70. package/shared/brush/BRUSH_TOOL.md +134 -0
  71. package/shared/brush/BrushOptions.svelte +200 -0
  72. package/shared/{tools → brush}/BrushSize.svelte +2 -30
  73. package/shared/{tools → brush}/ColorField.svelte +3 -1
  74. package/shared/{tools → brush}/ColorPicker.svelte +86 -9
  75. package/shared/{tools → brush}/ColorSwatch.svelte +95 -42
  76. package/shared/brush/brush-cursor.ts +408 -0
  77. package/shared/brush/brush-textures.ts +485 -0
  78. package/shared/brush/brush-utils.ts +76 -0
  79. package/shared/brush/brush.ts +510 -0
  80. package/shared/brush/types.ts +41 -0
  81. package/shared/core/EDITOR.md +182 -0
  82. package/shared/core/editor.ts +1788 -0
  83. package/shared/crop/CROP.md +139 -0
  84. package/shared/crop/crop.ts +1027 -0
  85. package/shared/image/IMAGE.md +135 -0
  86. package/shared/image/image.ts +298 -0
  87. package/shared/resize/resize.ts +1894 -0
  88. package/shared/types.ts +19 -0
  89. package/shared/utils/pixi.ts +19 -246
  90. package/shared/zoom/zoom.ts +729 -0
  91. package/dist/shared/layers/Layers.svelte +0 -231
  92. package/dist/shared/layers/Layers.svelte.d.ts +0 -18
  93. package/dist/shared/layers/utils.d.ts +0 -73
  94. package/dist/shared/layers/utils.js +0 -156
  95. package/dist/shared/tools/Brush.svelte +0 -215
  96. package/dist/shared/tools/Brush.svelte.d.ts +0 -29
  97. package/dist/shared/tools/Crop.svelte +0 -155
  98. package/dist/shared/tools/Crop.svelte.d.ts +0 -16
  99. package/dist/shared/tools/Cropper.svelte +0 -271
  100. package/dist/shared/tools/Cropper.svelte.d.ts +0 -41
  101. package/dist/shared/tools/Handle.svelte +0 -260
  102. package/dist/shared/tools/Handle.svelte.d.ts +0 -29
  103. package/dist/shared/tools/Sources.svelte +0 -257
  104. package/dist/shared/tools/Sources.svelte.d.ts +0 -34
  105. package/dist/shared/tools/Tools.svelte +0 -102
  106. package/dist/shared/tools/Tools.svelte.d.ts +0 -48
  107. package/dist/shared/tools/brush.d.ts +0 -62
  108. package/dist/shared/tools/brush.js +0 -133
  109. package/dist/shared/tools/crop.d.ts +0 -15
  110. package/dist/shared/tools/crop.js +0 -154
  111. package/dist/shared/tools/index.d.ts +0 -5
  112. package/dist/shared/tools/index.js +0 -5
  113. package/dist/shared/tools/sources.d.ts +0 -46
  114. package/dist/shared/tools/sources.js +0 -121
  115. package/dist/shared/tools/types.d.ts +0 -1
  116. package/shared/layers/Layers.svelte +0 -250
  117. package/shared/layers/utils.ts +0 -294
  118. package/shared/tools/Brush.svelte +0 -280
  119. package/shared/tools/BrushOptions.svelte +0 -180
  120. package/shared/tools/Crop.svelte +0 -189
  121. package/shared/tools/Cropper.svelte +0 -346
  122. package/shared/tools/Handle.svelte +0 -289
  123. package/shared/tools/Sources.svelte +0 -283
  124. package/shared/tools/Tools.svelte +0 -162
  125. package/shared/tools/brush.ts +0 -247
  126. package/shared/tools/crop.ts +0 -213
  127. package/shared/tools/index.ts +0 -5
  128. package/shared/tools/sources.ts +0 -195
  129. package/shared/tools/types.ts +0 -1
  130. /package/dist/shared/{tools → brush}/BrushSize.svelte.d.ts +0 -0
  131. /package/dist/shared/{tools/types.js → types.js} +0 -0
@@ -0,0 +1,19 @@
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";
15
+
16
+ export interface WebcamOptions {
17
+ mirror: boolean;
18
+ constraints: Record<string, any>;
19
+ }
@@ -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
  }