@gradio/image 0.3.6 → 0.4.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,55 @@
1
1
  # @gradio/image
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Highlights
6
+
7
+ #### New `ImageEditor` component ([#6169](https://github.com/gradio-app/gradio/pull/6169) [`9caddc17b`](https://github.com/gradio-app/gradio/commit/9caddc17b1dea8da1af8ba724c6a5eab04ce0ed8))
8
+
9
+ A brand new component, completely separate from `Image` that provides simple editing capabilities.
10
+
11
+ - Set background images from file uploads, webcam, or just paste!
12
+ - Crop images with an improved cropping UI. App authors can event set specific crop size, or crop ratios (`1:1`, etc)
13
+ - Paint on top of any image (or no image) and erase any mistakes!
14
+ - The ImageEditor supports layers, confining draw and erase actions to that layer.
15
+ - More flexible access to data. The image component returns a composite image representing the final state of the canvas as well as providing the background and all layers as individual images.
16
+ - Fully customisable. All features can be enabled and disabled. Even the brush color swatches can be customised.
17
+
18
+ <video src="https://user-images.githubusercontent.com/12937446/284027169-31188926-fd16-4a1c-8718-998e7aae4695.mp4" autoplay muted></video>
19
+
20
+ ```py
21
+
22
+ def fn(im):
23
+ im["composite"] # the full canvas
24
+ im["background"] # the background image
25
+ im["layers"] # a list of individual layers
26
+
27
+
28
+ im = gr.ImageEditor(
29
+ # decide which sources you'd like to accept
30
+ sources=["upload", "webcam", "clipboard"],
31
+ # set a cropsize constraint, can either be a ratio or a concrete [width, height]
32
+ crop_size="1:1",
33
+ # enable crop (or disable it)
34
+ transforms=["crop"],
35
+ # customise the brush
36
+ brush=Brush(
37
+ default_size="25", # or leave it as 'auto'
38
+ color_mode="fixed", # 'fixed' hides the user swatches and colorpicker, 'defaults' shows it
39
+ default_color="hotpink", # html names are supported
40
+ colors=[
41
+ "rgba(0, 150, 150, 1)", # rgb(a)
42
+ "#fff", # hex rgb
43
+ "hsl(360, 120, 120)" # in fact any valid colorstring
44
+ ]
45
+ ),
46
+ brush=Eraser(default_size="25")
47
+ )
48
+
49
+ ```
50
+
51
+ Thanks [@pngwn](https://github.com/pngwn)!
52
+
3
53
  ## 0.3.6
4
54
 
5
55
  ### Fixes
package/Index.svelte CHANGED
@@ -5,6 +5,7 @@
5
5
  export { default as BaseImageUploader } from "./shared/ImageUploader.svelte";
6
6
  export { default as BaseStaticImage } from "./shared/ImagePreview.svelte";
7
7
  export { default as BaseExample } from "./Example.svelte";
8
+ export { default as BaseImage } from "./shared/Image.svelte";
8
9
  </script>
9
10
 
10
11
  <script lang="ts">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/image",
3
- "version": "0.3.6",
3
+ "version": "0.4.0",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -10,13 +10,13 @@
10
10
  "cropperjs": "^1.5.12",
11
11
  "lazy-brush": "^1.0.1",
12
12
  "resize-observer-polyfill": "^1.5.1",
13
- "@gradio/atoms": "^0.2.2",
13
+ "@gradio/atoms": "^0.3.0",
14
+ "@gradio/icons": "^0.3.0",
14
15
  "@gradio/client": "^0.8.1",
15
- "@gradio/statustracker": "^0.3.2",
16
- "@gradio/upload": "^0.4.2",
17
- "@gradio/icons": "^0.2.1",
18
- "@gradio/wasm": "^0.3.0",
19
- "@gradio/utils": "^0.2.0"
16
+ "@gradio/statustracker": "^0.4.0",
17
+ "@gradio/upload": "^0.5.0",
18
+ "@gradio/utils": "^0.2.0",
19
+ "@gradio/wasm": "^0.3.0"
20
20
  },
21
21
  "main_changeset": true,
22
22
  "main": "./Index.svelte",
@@ -71,6 +71,7 @@
71
71
  height: var(--size-full);
72
72
  object-fit: contain;
73
73
  display: block;
74
+ border-radius: var(--radius-lg);
74
75
  }
75
76
 
76
77
  .selectable {
@@ -15,21 +15,17 @@
15
15
 
16
16
  const dispatch = createEventDispatcher<{
17
17
  stream: undefined;
18
- capture:
19
- | {
20
- data: FileReader["result"];
21
- name: string;
22
- is_example?: boolean;
23
- is_file: boolean;
24
- }
25
- | Blob;
18
+ capture: Blob;
26
19
  error: string;
27
20
  start_recording: undefined;
28
21
  stop_recording: undefined;
29
22
  }>();
30
23
 
31
24
  onMount(() => (canvas = document.createElement("canvas")));
32
-
25
+ const size = {
26
+ width: { ideal: 1920 },
27
+ height: { ideal: 1440 }
28
+ };
33
29
  async function access_webcam(device_id?: string): Promise<void> {
34
30
  if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
35
31
  dispatch("error", i18n("image.no_webcam_support"));
@@ -37,7 +33,7 @@
37
33
  }
38
34
  try {
39
35
  stream = await navigator.mediaDevices.getUserMedia({
40
- video: device_id ? { deviceId: { exact: device_id } } : true,
36
+ video: device_id ? { deviceId: { exact: device_id }, ...size } : size,
41
37
  audio: include_audio
42
38
  });
43
39
  video_source.srcObject = stream;
@@ -95,6 +91,7 @@
95
91
  ReaderObj.onload = function (e): void {
96
92
  if (e.target) {
97
93
  dispatch("capture", {
94
+ //@ts-ignore
98
95
  data: e.target.result,
99
96
  name: "sample." + mimeType.substring(6),
100
97
  is_example: false,