@gradio/image 0.23.2-dev.0 → 0.24.0-dev.2
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 +29 -0
- package/Index.svelte +105 -135
- package/dist/Example.svelte +7 -4
- package/dist/Example.svelte.d.ts +20 -18
- package/dist/Index.svelte +147 -146
- package/dist/Index.svelte.d.ts +3 -170
- package/dist/shared/Image.svelte +19 -2
- package/dist/shared/Image.svelte.d.ts +24 -19
- package/dist/shared/ImagePreview.svelte +51 -32
- package/dist/shared/ImagePreview.svelte.d.ts +33 -30
- package/dist/shared/ImageUploader.svelte +185 -138
- package/dist/shared/ImageUploader.svelte.d.ts +59 -49
- package/dist/shared/Webcam.svelte +264 -228
- package/dist/shared/Webcam.svelte.d.ts +42 -41
- package/dist/shared/WebcamPermissions.svelte +7 -3
- package/dist/shared/WebcamPermissions.svelte.d.ts +18 -16
- package/dist/shared/types.d.ts +30 -0
- package/package.json +11 -11
- package/shared/Image.svelte +18 -9
- package/shared/ImagePreview.svelte +8 -2
- package/shared/ImageUploader.svelte +9 -6
- package/shared/Webcam.svelte +6 -30
- package/shared/types.ts +33 -0
package/dist/shared/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { LoadingStatus } from "@gradio/statustracker";
|
|
2
|
+
import type { FileData } from "@gradio/client";
|
|
1
3
|
export interface Base64File {
|
|
2
4
|
url: string;
|
|
3
5
|
alt_text: string;
|
|
@@ -6,3 +8,31 @@ export interface WebcamOptions {
|
|
|
6
8
|
mirror: boolean;
|
|
7
9
|
constraints: MediaStreamConstraints;
|
|
8
10
|
}
|
|
11
|
+
export interface ImageProps {
|
|
12
|
+
_selectable: boolean;
|
|
13
|
+
sources: ("clipboard" | "webcam" | "upload")[];
|
|
14
|
+
height: number;
|
|
15
|
+
width: number;
|
|
16
|
+
webcam_options: WebcamOptions;
|
|
17
|
+
value: FileData | null;
|
|
18
|
+
buttons: string[];
|
|
19
|
+
pending: boolean;
|
|
20
|
+
streaming: boolean;
|
|
21
|
+
stream_every: number;
|
|
22
|
+
input_ready: boolean;
|
|
23
|
+
placeholder: string;
|
|
24
|
+
watermark: FileData | null;
|
|
25
|
+
}
|
|
26
|
+
export interface ImageEvents {
|
|
27
|
+
clear: void;
|
|
28
|
+
change: any;
|
|
29
|
+
stream: any;
|
|
30
|
+
select: any;
|
|
31
|
+
upload: any;
|
|
32
|
+
input: any;
|
|
33
|
+
clear_status: LoadingStatus;
|
|
34
|
+
share: any;
|
|
35
|
+
error: any;
|
|
36
|
+
close_stream: void;
|
|
37
|
+
edit: void;
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/image",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0-dev.2",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "ISC",
|
|
8
8
|
"private": false,
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"cropperjs": "^
|
|
11
|
-
"lazy-brush": "^
|
|
10
|
+
"cropperjs": "^2.0.1",
|
|
11
|
+
"lazy-brush": "^2.0.2",
|
|
12
12
|
"resize-observer-polyfill": "^1.5.1",
|
|
13
|
-
"@gradio/atoms": "^0.
|
|
14
|
-
"@gradio/
|
|
15
|
-
"@gradio/
|
|
16
|
-
"@gradio/
|
|
17
|
-
"@gradio/utils": "^0.10.
|
|
18
|
-
"@gradio/
|
|
13
|
+
"@gradio/atoms": "^0.19.0-dev.1",
|
|
14
|
+
"@gradio/client": "^2.0.0-dev.2",
|
|
15
|
+
"@gradio/statustracker": "^0.12.0-dev.1",
|
|
16
|
+
"@gradio/upload": "^0.17.2-dev.2",
|
|
17
|
+
"@gradio/utils": "^0.10.3-dev.0",
|
|
18
|
+
"@gradio/icons": "^0.15.0-dev.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@gradio/preview": "^0.
|
|
21
|
+
"@gradio/preview": "^0.15.0-dev.0"
|
|
22
22
|
},
|
|
23
23
|
"main_changeset": true,
|
|
24
24
|
"main": "./Index.svelte",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"svelte": "^
|
|
49
|
+
"svelte": "^5.43.4"
|
|
50
50
|
},
|
|
51
51
|
"repository": {
|
|
52
52
|
"type": "git",
|
package/shared/Image.svelte
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
let {
|
|
3
|
+
src,
|
|
4
|
+
restProps,
|
|
5
|
+
data_testid,
|
|
6
|
+
class_names
|
|
7
|
+
}: {
|
|
8
|
+
src: string;
|
|
9
|
+
restProps: object;
|
|
10
|
+
data_testid: string;
|
|
11
|
+
class_names: string[];
|
|
12
|
+
} = $props();
|
|
10
13
|
</script>
|
|
11
14
|
|
|
12
15
|
<!-- svelte-ignore a11y-missing-attribute -->
|
|
13
|
-
<img
|
|
16
|
+
<img
|
|
17
|
+
{src}
|
|
18
|
+
class={(class_names || []).join(" ")}
|
|
19
|
+
data-testid={data_testid}
|
|
20
|
+
{...restProps}
|
|
21
|
+
on:load
|
|
22
|
+
/>
|
|
14
23
|
|
|
15
24
|
<style>
|
|
16
25
|
img {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
export let i18n: I18nFormatter;
|
|
27
27
|
export let display_icon_button_wrapper_top_corner = false;
|
|
28
28
|
export let fullscreen = false;
|
|
29
|
+
export let show_button_background = true;
|
|
29
30
|
|
|
30
31
|
const dispatch = createEventDispatcher<{
|
|
31
32
|
change: string;
|
|
@@ -48,12 +49,13 @@
|
|
|
48
49
|
Icon={ImageIcon}
|
|
49
50
|
label={!show_label ? "" : label || i18n("image.image")}
|
|
50
51
|
/>
|
|
51
|
-
{#if value
|
|
52
|
+
{#if value == null || !value?.url}
|
|
52
53
|
<Empty unpadded_box={true} size="large"><ImageIcon /></Empty>
|
|
53
54
|
{:else}
|
|
54
55
|
<div class="image-container" bind:this={image_container}>
|
|
55
56
|
<IconButtonWrapper
|
|
56
57
|
display_top_corner={display_icon_button_wrapper_top_corner}
|
|
58
|
+
show_background={show_button_background}
|
|
57
59
|
>
|
|
58
60
|
{#if buttons === null ? true : buttons.includes("fullscreen")}
|
|
59
61
|
<FullscreenButton {fullscreen} on:fullscreen />
|
|
@@ -80,7 +82,11 @@
|
|
|
80
82
|
</IconButtonWrapper>
|
|
81
83
|
<button on:click={handle_click}>
|
|
82
84
|
<div class:selectable class="image-frame">
|
|
83
|
-
<Image
|
|
85
|
+
<Image
|
|
86
|
+
src={value.url}
|
|
87
|
+
restProps={{ loading: "lazy", alt: "" }}
|
|
88
|
+
on:load
|
|
89
|
+
/>
|
|
84
90
|
</div>
|
|
85
91
|
</button>
|
|
86
92
|
</div>
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
export let upload: Client["upload"];
|
|
35
35
|
export let stream_handler: Client["stream"];
|
|
36
36
|
export let stream_every: number;
|
|
37
|
-
|
|
38
|
-
export let modify_stream: (state: "open" | "closed" | "waiting") => void;
|
|
39
|
-
export let set_time_limit: (arg0: number) => void;
|
|
37
|
+
export let time_limit: number;
|
|
40
38
|
export let show_fullscreen_button = true;
|
|
39
|
+
export let stream_state: "open" | "waiting" | "closed" = "closed";
|
|
40
|
+
export let upload_promise: Promise<any> | null = null;
|
|
41
41
|
|
|
42
42
|
let upload_input: Upload;
|
|
43
43
|
export let uploading = false;
|
|
@@ -82,6 +82,7 @@
|
|
|
82
82
|
img_blob: Blob | any,
|
|
83
83
|
event: "change" | "stream" | "upload"
|
|
84
84
|
): Promise<void> {
|
|
85
|
+
console.log("handle_save", { event, img_blob });
|
|
85
86
|
if (event === "stream") {
|
|
86
87
|
dispatch("stream", {
|
|
87
88
|
value: { url: img_blob } as Base64File,
|
|
@@ -103,6 +104,7 @@
|
|
|
103
104
|
];
|
|
104
105
|
pending = true;
|
|
105
106
|
const f = await upload_input.load_files([f_], upload_id);
|
|
107
|
+
console.log("uploaded file", f);
|
|
106
108
|
if (event === "change" || event === "upload") {
|
|
107
109
|
value = f?.[0] || null;
|
|
108
110
|
await tick();
|
|
@@ -203,6 +205,7 @@
|
|
|
203
205
|
on:drop={on_drop}
|
|
204
206
|
>
|
|
205
207
|
<Upload
|
|
208
|
+
bind:upload_promise
|
|
206
209
|
hidden={value !== null || active_source === "webcam"}
|
|
207
210
|
bind:this={upload_input}
|
|
208
211
|
bind:uploading
|
|
@@ -233,6 +236,7 @@
|
|
|
233
236
|
on:drag
|
|
234
237
|
on:upload={(e) => handle_save(e.detail, "upload")}
|
|
235
238
|
on:close_stream
|
|
239
|
+
{stream_state}
|
|
236
240
|
mirror_webcam={webcam_options.mirror}
|
|
237
241
|
{stream_every}
|
|
238
242
|
{streaming}
|
|
@@ -240,15 +244,14 @@
|
|
|
240
244
|
include_audio={false}
|
|
241
245
|
{i18n}
|
|
242
246
|
{upload}
|
|
243
|
-
|
|
244
|
-
bind:set_time_limit
|
|
247
|
+
{time_limit}
|
|
245
248
|
webcam_constraints={webcam_options.constraints}
|
|
246
249
|
/>
|
|
247
250
|
{:else if value !== null && !streaming}
|
|
248
251
|
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
249
252
|
<!-- svelte-ignore a11y-no-static-element-interactions-->
|
|
250
253
|
<div class:selectable class="image-frame" on:click={handle_click}>
|
|
251
|
-
<Image src={value.url}
|
|
254
|
+
<Image src={value.url} restProps={{ alt: value.alt_text }} />
|
|
252
255
|
</div>
|
|
253
256
|
{/if}
|
|
254
257
|
</div>
|
package/shared/Webcam.svelte
CHANGED
|
@@ -22,26 +22,8 @@
|
|
|
22
22
|
let video_source: HTMLVideoElement;
|
|
23
23
|
let available_video_devices: MediaDeviceInfo[] = [];
|
|
24
24
|
let selected_device: MediaDeviceInfo | null = null;
|
|
25
|
-
let time_limit: number | null = null;
|
|
26
|
-
let stream_state: "open" | "waiting" | "closed" = "closed";
|
|
27
|
-
|
|
28
|
-
export const modify_stream: (state: "open" | "closed" | "waiting") => void = (
|
|
29
|
-
state: "open" | "closed" | "waiting"
|
|
30
|
-
) => {
|
|
31
|
-
if (state === "closed") {
|
|
32
|
-
time_limit = null;
|
|
33
|
-
stream_state = "closed";
|
|
34
|
-
value = null;
|
|
35
|
-
} else if (state === "waiting") {
|
|
36
|
-
stream_state = "waiting";
|
|
37
|
-
} else {
|
|
38
|
-
stream_state = "open";
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
25
|
|
|
42
|
-
export
|
|
43
|
-
if (recording) time_limit = time;
|
|
44
|
-
};
|
|
26
|
+
export let stream_state: "open" | "waiting" | "closed" = "closed";
|
|
45
27
|
|
|
46
28
|
let canvas: HTMLCanvasElement;
|
|
47
29
|
export let streaming = false;
|
|
@@ -56,7 +38,7 @@
|
|
|
56
38
|
export let i18n: I18nFormatter;
|
|
57
39
|
export let upload: Client["upload"];
|
|
58
40
|
export let value: FileData | null | Base64File = null;
|
|
59
|
-
|
|
41
|
+
export let time_limit: number | null = null;
|
|
60
42
|
const dispatch = createEventDispatcher<{
|
|
61
43
|
stream: Blob | string;
|
|
62
44
|
capture: FileData | Blob | null;
|
|
@@ -131,12 +113,13 @@
|
|
|
131
113
|
}
|
|
132
114
|
|
|
133
115
|
function take_picture(): void {
|
|
134
|
-
var context = canvas.getContext("2d")!;
|
|
135
116
|
if (
|
|
136
117
|
(!streaming || (streaming && recording)) &&
|
|
137
118
|
video_source.videoWidth &&
|
|
138
119
|
video_source.videoHeight
|
|
139
120
|
) {
|
|
121
|
+
console.log("Taking picture from webcam");
|
|
122
|
+
var context = canvas.getContext("2d")!;
|
|
140
123
|
canvas.width = video_source.videoWidth;
|
|
141
124
|
canvas.height = video_source.videoHeight;
|
|
142
125
|
context.drawImage(
|
|
@@ -241,13 +224,6 @@
|
|
|
241
224
|
|
|
242
225
|
if (!recording && stream) {
|
|
243
226
|
dispatch("close_stream");
|
|
244
|
-
stream.getTracks().forEach((track) => track.stop());
|
|
245
|
-
video_source.srcObject = null;
|
|
246
|
-
webcam_accessed = false;
|
|
247
|
-
window.setTimeout(() => {
|
|
248
|
-
value = null;
|
|
249
|
-
}, 500);
|
|
250
|
-
value = null;
|
|
251
227
|
}
|
|
252
228
|
}
|
|
253
229
|
|
|
@@ -360,12 +336,12 @@
|
|
|
360
336
|
use:click_outside={handle_click_outside}
|
|
361
337
|
on:change={handle_device_change}
|
|
362
338
|
>
|
|
363
|
-
<button
|
|
339
|
+
<!-- <button
|
|
364
340
|
class="inset-icon"
|
|
365
341
|
on:click|stopPropagation={() => (options_open = false)}
|
|
366
342
|
>
|
|
367
343
|
<DropdownArrow />
|
|
368
|
-
</button>
|
|
344
|
+
</button> -->
|
|
369
345
|
{#if available_video_devices.length === 0}
|
|
370
346
|
<option value="">{i18n("common.no_devices")}</option>
|
|
371
347
|
{:else}
|
package/shared/types.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { LoadingStatus } from "@gradio/statustracker";
|
|
2
|
+
import type { FileData } from "@gradio/client";
|
|
3
|
+
|
|
1
4
|
export interface Base64File {
|
|
2
5
|
url: string;
|
|
3
6
|
alt_text: string;
|
|
@@ -7,3 +10,33 @@ export interface WebcamOptions {
|
|
|
7
10
|
mirror: boolean;
|
|
8
11
|
constraints: MediaStreamConstraints;
|
|
9
12
|
}
|
|
13
|
+
|
|
14
|
+
export interface ImageProps {
|
|
15
|
+
_selectable: boolean;
|
|
16
|
+
sources: ("clipboard" | "webcam" | "upload")[];
|
|
17
|
+
height: number;
|
|
18
|
+
width: number;
|
|
19
|
+
webcam_options: WebcamOptions;
|
|
20
|
+
value: FileData | null;
|
|
21
|
+
buttons: string[];
|
|
22
|
+
pending: boolean;
|
|
23
|
+
streaming: boolean;
|
|
24
|
+
stream_every: number;
|
|
25
|
+
input_ready: boolean;
|
|
26
|
+
placeholder: string;
|
|
27
|
+
watermark: FileData | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ImageEvents {
|
|
31
|
+
clear: void;
|
|
32
|
+
change: any;
|
|
33
|
+
stream: any;
|
|
34
|
+
select: any;
|
|
35
|
+
upload: any;
|
|
36
|
+
input: any;
|
|
37
|
+
clear_status: LoadingStatus;
|
|
38
|
+
share: any;
|
|
39
|
+
error: any;
|
|
40
|
+
close_stream: void;
|
|
41
|
+
edit: void;
|
|
42
|
+
}
|