@gradio/imageeditor 0.6.0 → 0.7.1
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 +37 -0
- package/Index.svelte +5 -0
- package/package.json +10 -10
- package/shared/ImageEditor.svelte +17 -4
- package/shared/InteractiveImageEditor.svelte +12 -3
- package/shared/tools/Brush.svelte +2 -2
- package/shared/tools/Sources.svelte +9 -3
- package/shared/utils/pixi.ts +9 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @gradio/imageeditor
|
|
2
2
|
|
|
3
|
+
## 0.7.1
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- [#8252](https://github.com/gradio-app/gradio/pull/8252) [`22df61a`](https://github.com/gradio-app/gradio/commit/22df61a26adf8023f6dd49c051979990e8d3879a) - Client node fix. Thanks @pngwn!
|
|
8
|
+
|
|
9
|
+
### Dependency updates
|
|
10
|
+
|
|
11
|
+
- @gradio/atoms@0.7.3
|
|
12
|
+
- @gradio/statustracker@0.5.2
|
|
13
|
+
- @gradio/client@0.19.0
|
|
14
|
+
- @gradio/icons@0.4.1
|
|
15
|
+
- @gradio/image@0.11.1
|
|
16
|
+
- @gradio/upload@0.10.1
|
|
17
|
+
|
|
18
|
+
## 0.7.0
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
- [#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!
|
|
23
|
+
- [#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!
|
|
24
|
+
- [#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!
|
|
25
|
+
|
|
26
|
+
### Fixes
|
|
27
|
+
|
|
28
|
+
- [#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!
|
|
29
|
+
|
|
30
|
+
### Dependency updates
|
|
31
|
+
|
|
32
|
+
- @gradio/atoms@0.7.2
|
|
33
|
+
- @gradio/client@0.18.0
|
|
34
|
+
- @gradio/upload@0.10.0
|
|
35
|
+
- @gradio/utils@0.4.1
|
|
36
|
+
- @gradio/wasm@0.10.1
|
|
37
|
+
- @gradio/statustracker@0.5.1
|
|
38
|
+
- @gradio/image@0.11.0
|
|
39
|
+
|
|
3
40
|
## 0.6.0
|
|
4
41
|
|
|
5
42
|
### Highlights
|
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;
|
|
@@ -175,6 +176,7 @@
|
|
|
175
176
|
/>
|
|
176
177
|
|
|
177
178
|
<InteractiveImageEditor
|
|
179
|
+
{canvas_size}
|
|
178
180
|
on:change={() => handle_history_change()}
|
|
179
181
|
bind:image_id
|
|
180
182
|
{crop_size}
|
|
@@ -199,11 +201,14 @@
|
|
|
199
201
|
{brush}
|
|
200
202
|
{eraser}
|
|
201
203
|
changeable={attached_events.includes("apply")}
|
|
204
|
+
realtime={attached_events.includes("change")}
|
|
202
205
|
i18n={gradio.i18n}
|
|
203
206
|
{transforms}
|
|
204
207
|
accept_blobs={server.accept_blobs}
|
|
205
208
|
{layers}
|
|
206
209
|
status={loading_status?.status}
|
|
210
|
+
upload={gradio.client.upload}
|
|
211
|
+
stream_handler={gradio.client.stream}
|
|
207
212
|
></InteractiveImageEditor>
|
|
208
213
|
</Block>
|
|
209
214
|
{/if}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/imageeditor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -10,17 +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.
|
|
14
|
-
"@gradio/
|
|
15
|
-
"@gradio/
|
|
16
|
-
"@gradio/
|
|
17
|
-
"@gradio/
|
|
18
|
-
"@gradio/upload": "^0.
|
|
19
|
-
"@gradio/
|
|
20
|
-
"@gradio/
|
|
13
|
+
"@gradio/atoms": "^0.7.3",
|
|
14
|
+
"@gradio/icons": "^0.4.1",
|
|
15
|
+
"@gradio/client": "^0.19.0",
|
|
16
|
+
"@gradio/image": "^0.11.1",
|
|
17
|
+
"@gradio/statustracker": "^0.5.2",
|
|
18
|
+
"@gradio/upload": "^0.10.1",
|
|
19
|
+
"@gradio/utils": "^0.4.1",
|
|
20
|
+
"@gradio/wasm": "^0.10.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@gradio/preview": "^0.
|
|
23
|
+
"@gradio/preview": "^0.9.0"
|
|
24
24
|
},
|
|
25
25
|
"main_changeset": true,
|
|
26
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]
|
|
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
|
-
|
|
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(
|
|
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
|
|
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,
|
|
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"];
|
|
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}
|
|
@@ -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"];
|
|
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
|
-
|
|
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
|
|
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={
|
|
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
|
package/shared/utils/pixi.ts
CHANGED
|
@@ -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
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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,
|