@gradio/imageeditor 0.5.0 → 0.7.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 CHANGED
@@ -1,5 +1,71 @@
1
1
  # @gradio/imageeditor
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Features
6
+
7
+ - [#8121](https://github.com/gradio-app/gradio/pull/8121) [`f5b710c`](https://github.com/gradio-app/gradio/commit/f5b710c919b0ce604ea955f0d5f4faa91095ca4a) - chore(deps): update dependency eslint to v9. Thanks @renovate!
8
+ - [#8209](https://github.com/gradio-app/gradio/pull/8209) [`b9afe93`](https://github.com/gradio-app/gradio/commit/b9afe93915401df5bd6737c89395c2477acfa585) - Rename `eventSource_Factory` and `fetch_implementation`. Thanks @hannahblair!
9
+ - [#8127](https://github.com/gradio-app/gradio/pull/8127) [`24b2286`](https://github.com/gradio-app/gradio/commit/24b2286a22ed247b86ee299487174c8cea2988fe) - allow the canvas size to be set on the `ImageEditor`. Thanks @pngwn!
10
+
11
+ ### Fixes
12
+
13
+ - [#8179](https://github.com/gradio-app/gradio/pull/8179) [`6a218b4`](https://github.com/gradio-app/gradio/commit/6a218b4148095aaa0c58d8c20973ba01c8764fc2) - rework upload to be a class method + pass client into each component. Thanks @pngwn!
14
+
15
+ ### Dependency updates
16
+
17
+ - @gradio/atoms@0.7.2
18
+ - @gradio/client@0.18.0
19
+ - @gradio/upload@0.10.0
20
+ - @gradio/utils@0.4.1
21
+ - @gradio/wasm@0.10.1
22
+ - @gradio/statustracker@0.5.1
23
+ - @gradio/image@0.11.0
24
+
25
+ ## 0.6.0
26
+
27
+ ### Highlights
28
+
29
+ #### Setting File Upload Limits ([#7909](https://github.com/gradio-app/gradio/pull/7909) [`2afca65`](https://github.com/gradio-app/gradio/commit/2afca6541912b37dc84f447c7ad4af21607d7c72))
30
+
31
+ We have added a `max_file_size` size parameter to `launch()` that limits to size of files uploaded to the server. This limit applies to each individual file. This parameter can be specified as a string or an integer (corresponding to the size in bytes).
32
+
33
+ The following code snippet sets a max file size of 5 megabytes.
34
+
35
+ ```python
36
+ import gradio as gr
37
+
38
+ demo = gr.Interface(lambda x: x, "image", "image")
39
+
40
+ demo.launch(max_file_size="5mb")
41
+ # or
42
+ demo.launch(max_file_size=5 * gr.FileSize.MB)
43
+ ```
44
+
45
+ ![max_file_size_upload](https://github.com/gradio-app/gradio/assets/41651716/7547330c-a082-4901-a291-3f150a197e45)
46
+
47
+
48
+ #### Error states can now be cleared
49
+
50
+ When a component encounters an error, the error state shown in the UI can now be cleared by clicking on the `x` icon in the top right of the component. This applies to all types of errors, whether it's raised in the UI or the server.
51
+
52
+ ![error_modal_calculator](https://github.com/gradio-app/gradio/assets/41651716/16cb071c-accd-45a6-9c18-0dea27d4bd98)
53
+
54
+ Thanks @freddyaboulton!
55
+
56
+ ### Fixes
57
+
58
+ - [#8066](https://github.com/gradio-app/gradio/pull/8066) [`624f9b9`](https://github.com/gradio-app/gradio/commit/624f9b9477f74a581a6c14119234f9efdfcda398) - make gradio dev tools a local dependency rather than bundling. Thanks @pngwn!
59
+
60
+ ### Dependency updates
61
+
62
+ - @gradio/atoms@0.7.1
63
+ - @gradio/client@0.17.0
64
+ - @gradio/image@0.10.0
65
+ - @gradio/statustracker@0.5.0
66
+ - @gradio/upload@0.9.0
67
+ - @gradio/utils@0.4.0
68
+
3
69
  ## 0.5.0
4
70
 
5
71
  ### Features
package/Index.svelte CHANGED
@@ -54,6 +54,7 @@
54
54
  export let server: {
55
55
  accept_blobs: (a: any) => void;
56
56
  };
57
+ export let canvas_size: [number, number] | undefined;
57
58
 
58
59
  export let gradio: Gradio<{
59
60
  change: never;
@@ -66,6 +67,7 @@
66
67
  clear: never;
67
68
  select: SelectData;
68
69
  share: ShareData;
70
+ clear_status: LoadingStatus;
69
71
  }>;
70
72
 
71
73
  let editor_instance: InteractiveImageEditor;
@@ -136,6 +138,7 @@
136
138
  autoscroll={gradio.autoscroll}
137
139
  i18n={gradio.i18n}
138
140
  {...loading_status}
141
+ on:clear_status={() => gradio.dispatch("clear_status", loading_status)}
139
142
  />
140
143
  <StaticImage
141
144
  on:select={({ detail }) => gradio.dispatch("select", detail)}
@@ -169,9 +172,11 @@
169
172
  autoscroll={gradio.autoscroll}
170
173
  i18n={gradio.i18n}
171
174
  {...loading_status}
175
+ on:clear_status={() => gradio.dispatch("clear_status", loading_status)}
172
176
  />
173
177
 
174
178
  <InteractiveImageEditor
179
+ {canvas_size}
175
180
  on:change={() => handle_history_change()}
176
181
  bind:image_id
177
182
  {crop_size}
@@ -196,11 +201,14 @@
196
201
  {brush}
197
202
  {eraser}
198
203
  changeable={attached_events.includes("apply")}
204
+ realtime={attached_events.includes("change")}
199
205
  i18n={gradio.i18n}
200
206
  {transforms}
201
207
  accept_blobs={server.accept_blobs}
202
208
  {layers}
203
209
  status={loading_status?.status}
210
+ upload={gradio.client.upload}
211
+ stream_handler={gradio.client.stream_factory}
204
212
  ></InteractiveImageEditor>
205
213
  </Block>
206
214
  {/if}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/imageeditor",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -10,14 +10,17 @@
10
10
  "@types/tinycolor2": "^1.4.6",
11
11
  "pixi.js": "^7.3.2",
12
12
  "tinycolor2": "^1.6.0",
13
- "@gradio/atoms": "^0.7.0",
14
- "@gradio/client": "^0.16.0",
13
+ "@gradio/client": "^0.18.0",
14
+ "@gradio/atoms": "^0.7.2",
15
15
  "@gradio/icons": "^0.4.0",
16
- "@gradio/image": "^0.9.12",
17
- "@gradio/statustracker": "^0.4.12",
18
- "@gradio/upload": "^0.8.5",
19
- "@gradio/utils": "^0.3.2",
20
- "@gradio/wasm": "^0.10.0"
16
+ "@gradio/image": "^0.11.0",
17
+ "@gradio/statustracker": "^0.5.1",
18
+ "@gradio/utils": "^0.4.1",
19
+ "@gradio/upload": "^0.10.0",
20
+ "@gradio/wasm": "^0.10.1"
21
+ },
22
+ "devDependencies": {
23
+ "@gradio/preview": "^0.9.0"
21
24
  },
22
25
  "main_changeset": true,
23
26
  "main": "./Index.svelte",
@@ -62,7 +62,7 @@
62
62
  import { create_pixi_app, type ImageBlobs } from "./utils/pixi";
63
63
  import Controls from "./Controls.svelte";
64
64
  export let antialias = true;
65
- export let crop_size: [number, number] = [800, 600];
65
+ export let crop_size: [number, number] | undefined;
66
66
  export let changeable = false;
67
67
  export let history: boolean;
68
68
  export let bg = false;
@@ -73,8 +73,13 @@
73
73
  change: void;
74
74
  }>();
75
75
  export let crop_constraint = false;
76
+ export let canvas_size: [number, number] | undefined;
76
77
 
77
- let dimensions = writable(crop_size);
78
+ $: orig_canvas_size = canvas_size;
79
+
80
+ const BASE_DIMENSIONS: [number, number] = canvas_size || [800, 600];
81
+
82
+ let dimensions = writable(BASE_DIMENSIONS);
78
83
  export let height = 0;
79
84
 
80
85
  let editor_box: EditorContext["editor_box"] = writable({
@@ -260,7 +265,10 @@
260
265
  $: $position_spring && get_dimensions(canvas_wrap, pixi_target);
261
266
 
262
267
  export function handle_remove(): void {
263
- editor_context.reset(true, $dimensions);
268
+ editor_context.reset(
269
+ true,
270
+ orig_canvas_size ? orig_canvas_size : $dimensions
271
+ );
264
272
  if (!sources.length) {
265
273
  set_tool("draw");
266
274
  } else {
@@ -270,7 +278,12 @@
270
278
  }
271
279
 
272
280
  onMount(() => {
273
- const app = create_pixi_app(pixi_target, ...crop_size, antialias);
281
+ const _size = (canvas_size ? canvas_size : crop_size) || [800, 600];
282
+ const app = create_pixi_app({
283
+ target: pixi_target,
284
+ dimensions: _size,
285
+ antialias
286
+ });
274
287
 
275
288
  function resize(width: number, height: number): void {
276
289
  app.resize(width, height);
@@ -15,7 +15,7 @@
15
15
  <script lang="ts">
16
16
  import { createEventDispatcher } from "svelte";
17
17
  import { type I18nFormatter } from "@gradio/utils";
18
- import { prepare_files, upload, type FileData } from "@gradio/client";
18
+ import { prepare_files, type FileData, type Client } from "@gradio/client";
19
19
 
20
20
  import ImageEditor from "./ImageEditor.svelte";
21
21
  import Layers from "./layers/Layers.svelte";
@@ -44,6 +44,10 @@
44
44
  export let layers: boolean;
45
45
  export let accept_blobs: (a: any) => void;
46
46
  export let status: "pending" | "complete" | "error" = "complete";
47
+ export let canvas_size: [number, number] | undefined;
48
+ export let realtime: boolean;
49
+ export let upload: Client["upload"];
50
+ export let stream_handler: Client["stream_factory"];
47
51
 
48
52
  const dispatch = createEventDispatcher<{
49
53
  clear?: never;
@@ -70,7 +74,7 @@
70
74
  ? upload(
71
75
  await prepare_files([new File([blobs.background], "background.png")]),
72
76
  root
73
- )
77
+ )
74
78
  : Promise.resolve(null);
75
79
 
76
80
  const layers = blobs.layers
@@ -83,7 +87,7 @@
83
87
  ? upload(
84
88
  await prepare_files([new File([blobs.composite], "composite.png")]),
85
89
  root
86
- )
90
+ )
87
91
  : Promise.resolve(null);
88
92
 
89
93
  const [background, composite_, ...layers_] = await Promise.all([
@@ -131,6 +135,7 @@
131
135
  let uploading = false;
132
136
  let pending = false;
133
137
  async function handle_change(e: CustomEvent<Blob | any>): Promise<void> {
138
+ if (!realtime) return;
134
139
  if (uploading) {
135
140
  pending = true;
136
141
  return;
@@ -199,6 +204,8 @@
199
204
  label={label || i18n("image.image")}
200
205
  />
201
206
  <ImageEditor
207
+ {canvas_size}
208
+ crop_size={Array.isArray(crop_size) ? crop_size : undefined}
202
209
  bind:this={editor}
203
210
  bind:height={editor_height}
204
211
  {changeable}
@@ -217,6 +224,8 @@
217
224
  {i18n}
218
225
  {root}
219
226
  {sources}
227
+ {upload}
228
+ {stream_handler}
220
229
  bind:bg
221
230
  bind:active_mode
222
231
  background_file={value?.background || value?.composite || null}
@@ -51,8 +51,8 @@
51
51
  default_color === "auto"
52
52
  ? processed_colors[0]
53
53
  : !default_color
54
- ? "black"
55
- : process_color(default_color);
54
+ ? "black"
55
+ : process_color(default_color);
56
56
 
57
57
  let brush_options: brush_option_type = false;
58
58
 
@@ -11,6 +11,7 @@
11
11
  import { Webcam } from "@gradio/image";
12
12
  import { type I18nFormatter } from "@gradio/utils";
13
13
  import { IconButton } from "@gradio/atoms";
14
+ import { type Client } from "@gradio/client";
14
15
 
15
16
  import { add_bg_color, add_bg_image } from "./sources";
16
17
  import type { FileData } from "@gradio/client";
@@ -24,6 +25,8 @@
24
25
  ];
25
26
  export let mirror_webcam = true;
26
27
  export let i18n: I18nFormatter;
28
+ export let upload: Client["upload"];
29
+ export let stream_handler: Client["stream_factory"];
27
30
 
28
31
  const { active_tool } = getContext<ToolContext>(TOOL_KEY);
29
32
  const { pixi, dimensions, register_context, reset, editor_box } =
@@ -43,7 +46,7 @@
43
46
  order: 0,
44
47
  id: "bg_upload",
45
48
  cb() {
46
- upload.open_file_upload();
49
+ upload_component.open_file_upload();
47
50
 
48
51
  $active_tool = "bg";
49
52
  }
@@ -74,7 +77,7 @@
74
77
  .map((src) => sources_meta[src])
75
78
  .sort((a, b) => a.order - b.order);
76
79
 
77
- let upload: Upload;
80
+ let upload_component: Upload;
78
81
 
79
82
  async function process_clipboard(): Promise<void> {
80
83
  const items = await navigator.clipboard.read();
@@ -179,13 +182,15 @@
179
182
  <div class="upload-container">
180
183
  <Upload
181
184
  hidden={true}
182
- bind:this={upload}
185
+ bind:this={upload_component}
183
186
  filetype="image/*"
184
187
  on:load={handle_upload}
185
188
  on:error
186
189
  {root}
187
190
  disable_click={!sources.includes("upload")}
188
191
  format="blob"
192
+ {upload}
193
+ {stream_handler}
189
194
  ></Upload>
190
195
  {#if active_mode === "webcam"}
191
196
  <div
@@ -196,6 +201,7 @@
196
201
  >
197
202
  <div class="modal-inner">
198
203
  <Webcam
204
+ {upload}
199
205
  {root}
200
206
  on:capture={handle_upload}
201
207
  on:error
@@ -73,12 +73,15 @@ export interface PixiApp {
73
73
  * @param antialias Whether to use antialiasing
74
74
  * @returns object with pixi container and renderer
75
75
  */
76
- export function create_pixi_app(
77
- target: HTMLElement,
78
- width: number,
79
- height: number,
80
- antialias: boolean
81
- ): PixiApp {
76
+ export function create_pixi_app({
77
+ target,
78
+ dimensions: [width, height],
79
+ antialias
80
+ }: {
81
+ target: HTMLElement;
82
+ dimensions: [number, number];
83
+ antialias: boolean;
84
+ }): PixiApp {
82
85
  const ratio = window.devicePixelRatio || 1;
83
86
  const app = new Application({
84
87
  width,