elismasilva commited on
Commit
b83d9ce
·
verified ·
1 Parent(s): 5da0154

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +215 -215
  2. src/demo/app.py +3 -3
app.py CHANGED
@@ -1,216 +1,216 @@
1
- from dataclasses import dataclass, field
2
- from typing import List, Any
3
- import gradio as gr
4
- from gradio_imagemeta import ImageMeta
5
- from gradio_imagemeta.helpers import extract_metadata, add_metadata, transfer_metadata
6
- from gradio_propertysheet import PropertySheet
7
- from gradio_propertysheet.helpers import build_dataclass_fields, create_dataclass_instance
8
- from pathlib import Path
9
-
10
- output_dir = Path("outputs")
11
- output_dir.mkdir(exist_ok=True)
12
-
13
- @dataclass
14
- class ImageSettings:
15
- """Configuration for image metadata settings."""
16
- model: str = field(default="", metadata={"label": "Model"})
17
- f_number: str = field(default="", metadata={"label": "FNumber"})
18
- iso_speed_ratings: str = field(default="", metadata={"label": "ISOSpeedRatings"})
19
- s_churn: float = field(
20
- default=0.0,
21
- metadata={"component": "slider", "label": "Schurn", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
22
- )
23
-
24
- @dataclass
25
- class PropertyConfig:
26
- """Root configuration for image properties, including nested image settings."""
27
- image_settings: ImageSettings = field(default_factory=ImageSettings)
28
- description: str = field(default="", metadata={"label": "Description"})
29
-
30
- def process_example_images(img_custom_path: str, img_all_path: str) -> tuple[str, str]:
31
- """
32
- Processes example image paths for display in ImageMeta components.
33
-
34
- Args:
35
- img_custom_path: File path for the image to display in img_custom.
36
- img_all_path: File path for the image to display in img_all.
37
-
38
- Returns:
39
- Tuple of file paths for img_custom and img_all outputs.
40
- """
41
- # Verify file existence
42
- if not Path(img_custom_path.path).is_file():
43
- raise FileNotFoundError(f"Image not found: {img_custom_path}")
44
- if not Path(img_all_path.path).is_file():
45
- raise FileNotFoundError(f"Image not found: {img_all_path}")
46
-
47
- # Return file paths as strings (ImageMeta accepts file paths as input)
48
- return img_custom_path.path, img_all_path.path
49
-
50
- def handle_load_metadata(image_data: ImageMeta | None) -> List[Any]:
51
- """
52
- Processes image metadata and maps it to output components.
53
-
54
- Args:
55
- image_data: ImageMeta object containing image data and metadata, or None.
56
-
57
- Returns:
58
- A list of values for output components (Textbox, Slider, or PropertySheet instances).
59
- """
60
- if not image_data:
61
- return [gr.Textbox(value="") for _ in output_fields]
62
-
63
- metadata = extract_metadata(image_data, only_custom_metadata=True)
64
- dataclass_fields = build_dataclass_fields(PropertyConfig)
65
- raw_values = transfer_metadata(output_fields, metadata, dataclass_fields)
66
-
67
- output_values = [gr.skip()] * len(output_fields)
68
- for i, (component, value) in enumerate(zip(output_fields, raw_values)):
69
- if hasattr(component, 'root_label'):
70
- output_values[i] = create_dataclass_instance(PropertyConfig, value)
71
- else:
72
- output_values[i] = gr.Textbox(value=value)
73
-
74
- return output_values
75
-
76
- def save_image_with_metadata(image_data: Any, *inputs: Any) -> str | None:
77
- """
78
- Saves an image with updated metadata to a file.
79
-
80
- Args:
81
- image_data: Input image data (e.g., file path or PIL Image).
82
- *inputs: Variable number of input values from UI components (Textbox, Slider).
83
-
84
- Returns:
85
- The file path of the saved image, or None if no image is provided.
86
- """
87
- if not image_data:
88
- return None
89
-
90
- params = list(inputs)
91
- image_params = dict(zip(input_fields.keys(), params))
92
- dataclass_fields = build_dataclass_fields(PropertyConfig)
93
- metadata = {label: image_params.get(label, "") for label in dataclass_fields.keys()}
94
-
95
- new_filepath = output_dir / "image_with_meta.png"
96
- add_metadata(image_data, metadata, new_filepath)
97
-
98
- return str(new_filepath)
99
-
100
- initial_property_from_meta_config = PropertyConfig()
101
-
102
- with gr.Blocks() as demo:
103
- gr.Markdown("# ImageMeta Component Demo")
104
- gr.Markdown(
105
- """
106
- **To Test:**
107
- 1. Upload an image with EXIF or PNG metadata using either the "Upload Imagem (Custom metadata only)" component or the "Upload Imagem (all metadata)" component.
108
- 2. Click the 'Info' icon (ⓘ) in the top-left of the image component to view the metadata panel.
109
- 3. Click 'Load Metadata' in the popup to populate the fields below with metadata values (`Model`, `FNumber`, `ISOSpeedRatings`, `Schurn`, `Description`).
110
- 4. The section below displays how metadata is rendered in components and the `PropertySheet` custom component, showing the hierarchical structure of the image settings.
111
- 5. In the "Metadata Viewer" section, you can add field values as metadata to a previously uploaded image in "Upload Image (Custom metadata only)." Then click 'Add metadata and save image' to save a new image with the metadata.
112
- """
113
- )
114
- property_sheet_state = gr.State(value=initial_property_from_meta_config)
115
- with gr.Row():
116
- img_custom = ImageMeta(
117
- label="Upload Image (Custom metadata only)",
118
- type="filepath",
119
- width=300,
120
- height=400,
121
- interactive=False
122
- )
123
- img_all = ImageMeta(
124
- label="Upload Image (All metadata)",
125
- only_custom_metadata=False,
126
- type="filepath",
127
- width=300,
128
- height=400,
129
- popup_metadata_height=400,
130
- popup_metadata_width=500,
131
- interactive=False
132
- )
133
-
134
- gr.Markdown("## Metadata Viewer")
135
- gr.Markdown("### Individual Components")
136
- with gr.Row():
137
- model_box = gr.Textbox(label="Model")
138
- fnumber_box = gr.Textbox(label="FNumber")
139
- iso_box = gr.Textbox(label="ISOSpeedRatings")
140
- s_churn = gr.Slider(label="Schurn", value=1.0, minimum=0.0, maximum=1.0, step=0.1)
141
- description_box = gr.Textbox(label="Description")
142
-
143
- gr.Markdown("### PropertySheet Component")
144
- with gr.Row():
145
- property_sheet = PropertySheet(
146
- value=initial_property_from_meta_config,
147
- label="Image Settings",
148
- width=400,
149
- height=550,
150
- visible=True,
151
- root_label="General"
152
- )
153
- gr.Markdown("## Metadata Editor")
154
- with gr.Row():
155
- save_button = gr.Button("Add Metadata and Save Image")
156
- saved_file_output = gr.File(label="Download Image")
157
-
158
- with gr.Row():
159
- gr.Examples(
160
- examples=[
161
- ["./src/examples/image_with_meta.png", "./src/examples/image_with_meta.png"]
162
- ],
163
- fn=process_example_images,
164
- inputs=[img_custom, img_all],
165
- outputs=[img_custom, img_all],
166
- cache_examples=True
167
- )
168
-
169
- input_fields = {
170
- "Model": model_box,
171
- "FNumber": fnumber_box,
172
- "ISOSpeedRatings": iso_box,
173
- "Schurn": s_churn,
174
- "Description": description_box
175
- }
176
-
177
- output_fields = [
178
- property_sheet,
179
- model_box,
180
- fnumber_box,
181
- iso_box,
182
- s_churn,
183
- description_box
184
- ]
185
-
186
- img_custom.load_metadata(handle_load_metadata, inputs=img_custom, outputs=output_fields)
187
- img_all.load_metadata(handle_load_metadata, inputs=img_all, outputs=output_fields)
188
-
189
- def handle_render_change(updated_config: PropertyConfig, current_state: PropertyConfig):
190
- """
191
- Updates the PropertySheet state when its configuration changes.
192
-
193
- Args:
194
- updated_config: The new PropertyConfig instance from the PropertySheet.
195
- current_state: The current PropertyConfig state.
196
-
197
- Returns:
198
- A tuple of (updated_config, updated_config) or (current_state, current_state) if updated_config is None.
199
- """
200
- if updated_config is None:
201
- return current_state, current_state
202
- return updated_config, updated_config
203
-
204
- property_sheet.change(
205
- fn=handle_render_change,
206
- inputs=[property_sheet, property_sheet_state],
207
- outputs=[property_sheet, property_sheet_state]
208
- )
209
- save_button.click(
210
- save_image_with_metadata,
211
- inputs=[img_custom, *input_fields.values()],
212
- outputs=[saved_file_output]
213
- )
214
-
215
- if __name__ == "__main__":
216
  demo.launch()
 
1
+ from dataclasses import dataclass, field
2
+ from typing import List, Any
3
+ import gradio as gr
4
+ from gradio_imagemeta import ImageMeta
5
+ from gradio_imagemeta.helpers import extract_metadata, add_metadata, transfer_metadata
6
+ from gradio_propertysheet import PropertySheet
7
+ from gradio_propertysheet.helpers import build_dataclass_fields, create_dataclass_instance
8
+ from pathlib import Path
9
+
10
+ output_dir = Path("outputs")
11
+ output_dir.mkdir(exist_ok=True)
12
+
13
+ @dataclass
14
+ class ImageSettings:
15
+ """Configuration for image metadata settings."""
16
+ model: str = field(default="", metadata={"label": "Model"})
17
+ f_number: str = field(default="", metadata={"label": "FNumber"})
18
+ iso_speed_ratings: str = field(default="", metadata={"label": "ISOSpeedRatings"})
19
+ s_churn: float = field(
20
+ default=0.0,
21
+ metadata={"component": "slider", "label": "Schurn", "minimum": 0.0, "maximum": 1.0, "step": 0.01},
22
+ )
23
+
24
+ @dataclass
25
+ class PropertyConfig:
26
+ """Root configuration for image properties, including nested image settings."""
27
+ image_settings: ImageSettings = field(default_factory=ImageSettings)
28
+ description: str = field(default="", metadata={"label": "Description"})
29
+
30
+ def process_example_images(img_custom_path: str, img_all_path: str) -> tuple[str, str]:
31
+ """
32
+ Processes example image paths for display in ImageMeta components.
33
+
34
+ Args:
35
+ img_custom_path: File path for the image to display in img_custom.
36
+ img_all_path: File path for the image to display in img_all.
37
+
38
+ Returns:
39
+ Tuple of file paths for img_custom and img_all outputs.
40
+ """
41
+ # Verify file existence
42
+ if not Path(img_custom_path.path).is_file():
43
+ raise FileNotFoundError(f"Image not found: {img_custom_path}")
44
+ if not Path(img_all_path.path).is_file():
45
+ raise FileNotFoundError(f"Image not found: {img_all_path}")
46
+
47
+ # Return file paths as strings (ImageMeta accepts file paths as input)
48
+ return img_custom_path.path, img_all_path.path
49
+
50
+ def handle_load_metadata(image_data: ImageMeta | None) -> List[Any]:
51
+ """
52
+ Processes image metadata and maps it to output components.
53
+
54
+ Args:
55
+ image_data: ImageMeta object containing image data and metadata, or None.
56
+
57
+ Returns:
58
+ A list of values for output components (Textbox, Slider, or PropertySheet instances).
59
+ """
60
+ if not image_data:
61
+ return [gr.Textbox(value="") for _ in output_fields]
62
+
63
+ metadata = extract_metadata(image_data, only_custom_metadata=True)
64
+ dataclass_fields = build_dataclass_fields(PropertyConfig)
65
+ raw_values = transfer_metadata(output_fields, metadata, dataclass_fields)
66
+
67
+ output_values = [gr.skip()] * len(output_fields)
68
+ for i, (component, value) in enumerate(zip(output_fields, raw_values)):
69
+ if hasattr(component, 'root_label'):
70
+ output_values[i] = create_dataclass_instance(PropertyConfig, value)
71
+ else:
72
+ output_values[i] = gr.Textbox(value=value)
73
+
74
+ return output_values
75
+
76
+ def save_image_with_metadata(image_data: Any, *inputs: Any) -> str | None:
77
+ """
78
+ Saves an image with updated metadata to a file.
79
+
80
+ Args:
81
+ image_data: Input image data (e.g., file path or PIL Image).
82
+ *inputs: Variable number of input values from UI components (Textbox, Slider).
83
+
84
+ Returns:
85
+ The file path of the saved image, or None if no image is provided.
86
+ """
87
+ if not image_data:
88
+ return None
89
+
90
+ params = list(inputs)
91
+ image_params = dict(zip(input_fields.keys(), params))
92
+ dataclass_fields = build_dataclass_fields(PropertyConfig)
93
+ metadata = {label: image_params.get(label, "") for label in dataclass_fields.keys()}
94
+
95
+ new_filepath = output_dir / "image_with_meta.png"
96
+ add_metadata(image_data, metadata, new_filepath)
97
+
98
+ return str(new_filepath)
99
+
100
+ initial_property_from_meta_config = PropertyConfig()
101
+
102
+ with gr.Blocks() as demo:
103
+ gr.Markdown("# ImageMeta Component Demo")
104
+ gr.Markdown(
105
+ """
106
+ **To Test:**
107
+ 1. Upload an image with EXIF or PNG metadata using either the "Upload Imagem (Custom metadata only)" component or the "Upload Imagem (all metadata)" component.
108
+ 2. Click the 'Info' icon (ⓘ) in the top-left of the image component to view the metadata panel.
109
+ 3. Click 'Load Metadata' in the popup to populate the fields below with metadata values (`Model`, `FNumber`, `ISOSpeedRatings`, `Schurn`, `Description`).
110
+ 4. The section below displays how metadata is rendered in components and the `PropertySheet` custom component, showing the hierarchical structure of the image settings.
111
+ 5. In the "Metadata Viewer" section, you can add field values as metadata to a previously uploaded image in "Upload Image (Custom metadata only)." Then click 'Add metadata and save image' to save a new image with the metadata.
112
+ """
113
+ )
114
+ property_sheet_state = gr.State(value=initial_property_from_meta_config)
115
+ with gr.Row():
116
+ img_custom = ImageMeta(
117
+ label="Upload Image (Custom metadata only)",
118
+ type="filepath",
119
+ width=300,
120
+ height=400,
121
+ interactive=True
122
+ )
123
+ img_all = ImageMeta(
124
+ label="Upload Image (All metadata)",
125
+ only_custom_metadata=False,
126
+ type="filepath",
127
+ width=300,
128
+ height=400,
129
+ popup_metadata_height=400,
130
+ popup_metadata_width=500,
131
+ interactive=True
132
+ )
133
+
134
+ gr.Markdown("## Metadata Viewer")
135
+ gr.Markdown("### Individual Components")
136
+ with gr.Row():
137
+ model_box = gr.Textbox(label="Model")
138
+ fnumber_box = gr.Textbox(label="FNumber")
139
+ iso_box = gr.Textbox(label="ISOSpeedRatings")
140
+ s_churn = gr.Slider(label="Schurn", value=1.0, minimum=0.0, maximum=1.0, step=0.1)
141
+ description_box = gr.Textbox(label="Description")
142
+
143
+ gr.Markdown("### PropertySheet Component")
144
+ with gr.Row():
145
+ property_sheet = PropertySheet(
146
+ value=initial_property_from_meta_config,
147
+ label="Image Settings",
148
+ width=400,
149
+ height=550,
150
+ visible=True,
151
+ root_label="General"
152
+ )
153
+ gr.Markdown("## Metadata Editor")
154
+ with gr.Row():
155
+ save_button = gr.Button("Add Metadata and Save Image")
156
+ saved_file_output = gr.File(label="Download Image")
157
+
158
+ with gr.Row():
159
+ gr.Examples(
160
+ examples=[
161
+ ["./src/examples/image_with_meta.png", "./src/examples/image_with_meta.png"]
162
+ ],
163
+ fn=process_example_images,
164
+ inputs=[img_custom, img_all],
165
+ outputs=[img_custom, img_all],
166
+ cache_examples=True
167
+ )
168
+
169
+ input_fields = {
170
+ "Model": model_box,
171
+ "FNumber": fnumber_box,
172
+ "ISOSpeedRatings": iso_box,
173
+ "Schurn": s_churn,
174
+ "Description": description_box
175
+ }
176
+
177
+ output_fields = [
178
+ property_sheet,
179
+ model_box,
180
+ fnumber_box,
181
+ iso_box,
182
+ s_churn,
183
+ description_box
184
+ ]
185
+
186
+ img_custom.load_metadata(handle_load_metadata, inputs=img_custom, outputs=output_fields)
187
+ img_all.load_metadata(handle_load_metadata, inputs=img_all, outputs=output_fields)
188
+
189
+ def handle_render_change(updated_config: PropertyConfig, current_state: PropertyConfig):
190
+ """
191
+ Updates the PropertySheet state when its configuration changes.
192
+
193
+ Args:
194
+ updated_config: The new PropertyConfig instance from the PropertySheet.
195
+ current_state: The current PropertyConfig state.
196
+
197
+ Returns:
198
+ A tuple of (updated_config, updated_config) or (current_state, current_state) if updated_config is None.
199
+ """
200
+ if updated_config is None:
201
+ return current_state, current_state
202
+ return updated_config, updated_config
203
+
204
+ property_sheet.change(
205
+ fn=handle_render_change,
206
+ inputs=[property_sheet, property_sheet_state],
207
+ outputs=[property_sheet, property_sheet_state]
208
+ )
209
+ save_button.click(
210
+ save_image_with_metadata,
211
+ inputs=[img_custom, *input_fields.values()],
212
+ outputs=[saved_file_output]
213
+ )
214
+
215
+ if __name__ == "__main__":
216
  demo.launch()
src/demo/app.py CHANGED
@@ -118,7 +118,7 @@ with gr.Blocks() as demo:
118
  type="filepath",
119
  width=300,
120
  height=400,
121
- interactive=False
122
  )
123
  img_all = ImageMeta(
124
  label="Upload Image (All metadata)",
@@ -128,7 +128,7 @@ with gr.Blocks() as demo:
128
  height=400,
129
  popup_metadata_height=400,
130
  popup_metadata_width=500,
131
- interactive=False
132
  )
133
 
134
  gr.Markdown("## Metadata Viewer")
@@ -158,7 +158,7 @@ with gr.Blocks() as demo:
158
  with gr.Row():
159
  gr.Examples(
160
  examples=[
161
- ["./examples/image_with_meta.png", "./examples/image_with_meta.png"]
162
  ],
163
  fn=process_example_images,
164
  inputs=[img_custom, img_all],
 
118
  type="filepath",
119
  width=300,
120
  height=400,
121
+ interactive=True
122
  )
123
  img_all = ImageMeta(
124
  label="Upload Image (All metadata)",
 
128
  height=400,
129
  popup_metadata_height=400,
130
  popup_metadata_width=500,
131
+ interactive=True
132
  )
133
 
134
  gr.Markdown("## Metadata Viewer")
 
158
  with gr.Row():
159
  gr.Examples(
160
  examples=[
161
+ ["./src/examples/image_with_meta.png", "./src/examples/image_with_meta.png"]
162
  ],
163
  fn=process_example_images,
164
  inputs=[img_custom, img_all],