elismasilva's picture
Upload folder using huggingface_hub
8497828 verified
import gradio as gr
from typing import List, Any, Literal
from gradio_imagemeta import ImageMeta
from gradio_imagemeta.helpers import add_metadata, transfer_metadata
from gradio_propertysheet import PropertySheet
from gradio_propertysheet.helpers import flatten_dataclass_with_labels
from pathlib import Path
from ui_config import PropertyConfig
output_dir = Path("outputs")
output_dir.mkdir(exist_ok=True)
def load_default_image():
return "src/examples/image_with_meta.png"
def handle_load_metadata(image_data: gr.EventData) -> List[Any]:
"""
Processes image metadata by calling the agnostic `transfer_metadata` helper.
"""
if not image_data or not hasattr(image_data, "_data"):
return [gr.skip()] * len(output_fields)
metadata = image_data._data
if not metadata:
return [gr.skip()] * len(output_fields)
# --- UI-Specific Configuration ---
# Define the map that tells the helper how to process the PropertySheet.
sheet_map = {
id(property_sheet): {
"type": property_sheet._dataclass_type,
"prefixes": [] # No prefixes needed for this simple case
}
}
gradio_map = {
id(component): label
for label, component in input_fields.items()
}
# Call the agnostic helper function to do the heavy lifting.
return transfer_metadata(
output_fields=output_fields,
metadata=metadata,
propertysheet_map=sheet_map,
gradio_component_map=gradio_map,
remove_prefix_from_keys=False
)
def save_image_with_metadata(
image_data: Any,
format: Literal[".png", ".png"],
sheet_state: PropertyConfig,
model: str,
f_number: str,
iso: str,
s_churn_val: float,
description: str
) -> str | None:
"""
Saves an image with updated metadata, merging data from the PropertySheet
and individual UI components.
This example deals with the PropertySheet component and the individual gradio components.
Since they have the same labels here, we'll simply replace the metadata with each other's values.
"""
if not image_data:
return None
metadata = flatten_dataclass_with_labels(sheet_state)
individual_component_values = {
"Model": model,
"FNumber": f_number,
"ISOSpeedRatings": iso,
"Schurn": s_churn_val,
"Description": description
}
metadata["Image Settings - Model"] = individual_component_values["Model"]
metadata["Image Settings - FNumber"] = individual_component_values["FNumber"]
metadata["Image Settings - ISOSpeedRatings"] = individual_component_values["ISOSpeedRatings"]
metadata["Image Settings - Schurn"] = individual_component_values["Schurn"]
metadata["Description"] = individual_component_values["Description"]
final_metadata = {str(key): value for key, value in metadata.items()}
new_filepath = output_dir / f"image_with_meta{format}"
add_metadata(image_data, new_filepath, final_metadata)
return str(new_filepath)
initial_property_from_meta_config = PropertyConfig()
with gr.Blocks(theme=gr.themes.Ocean()) as demo:
gr.Markdown("# ImageMeta Component Demo")
gr.Markdown("""
2. Upload demo image or an image with EXIF or PNG metadata using either the "Upload Imagem (Custom metadata only)" component or the "Upload Imagem (all metadata)" component.
3. Click the 'Info' icon (ⓘ) in the top-left of the image component to view the metadata panel.
4. Click 'Load Metadata' in the popup to populate the fields below with metadata values (`Model`, `FNumber`, `ISOSpeedRatings`, `Schurn`, `Description`).
5. The section below displays how metadata is rendered in components and the `PropertySheet` custom component, showing the hierarchical structure of the image settings.
6. 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.
"""
)
property_sheet_state = gr.State(value=initial_property_from_meta_config)
with gr.Row():
img_custom = ImageMeta(
label="Upload Image (Custom metadata only)",
type="filepath",
width=600,
height=400,
popup_metadata_height=350,
popup_metadata_width=550,
interactive=True,
only_custom_metadata=True
)
img_all = ImageMeta(
label="Upload Image (All metadata)",
only_custom_metadata=False,
type="filepath",
width=600,
height=400,
popup_metadata_height=350,
popup_metadata_width=550,
interactive=True
)
gr.Markdown("## Metadata Viewer")
gr.Markdown("### Individual Components")
with gr.Row():
model_box = gr.Textbox(label="Model")
fnumber_box = gr.Textbox(label="FNumber")
iso_box = gr.Textbox(label="ISOSpeedRatings")
s_churn = gr.Slider(label="Schurn", value=1.0, minimum=0.0, maximum=1.0, step=0.1)
description_box = gr.Textbox(label="Description", lines=2)
gr.Markdown("### PropertySheet Component")
with gr.Row():
property_sheet = PropertySheet(
value=initial_property_from_meta_config,
label="Image Settings",
width=400,
height=550,
visible=True,
root_label="General"
)
gr.Markdown("## Metadata Editor")
with gr.Row():
save_format = gr.Radio(label="Image Format", choices=[".png", ".jpg"], value=".png")
save_button = gr.Button("Add Metadata and Save Image")
saved_file_output = gr.File(label="Download Image")
input_fields = {
"Model": model_box,
"FNumber": fnumber_box,
"ISOSpeedRatings": iso_box,
"Schurn": s_churn,
"Description": description_box
}
output_fields = [
property_sheet,
model_box,
fnumber_box,
iso_box,
s_churn,
description_box
]
img_custom.load_metadata(handle_load_metadata, inputs=None, outputs=output_fields)
img_all.load_metadata(handle_load_metadata, inputs=None, outputs=output_fields)
def handle_render_change(updated_config: PropertyConfig, current_state: PropertyConfig):
"""
Updates the PropertySheet state when its configuration changes.
Args:
updated_config: The new PropertyConfig instance from the PropertySheet.
current_state: The current PropertyConfig state.
Returns:
A tuple of (updated_config, updated_config) or (current_state, current_state) if updated_config is None.
"""
if updated_config is None:
return current_state, current_state
return updated_config, updated_config
property_sheet.change(
fn=handle_render_change,
inputs=[property_sheet, property_sheet_state],
outputs=[property_sheet, property_sheet_state]
)
save_button.click(
save_image_with_metadata,
inputs=[img_custom, save_format, property_sheet, *input_fields.values()],
outputs=[saved_file_output]
)
demo.load(
fn=load_default_image,
inputs=None,
outputs=img_custom
)
if __name__ == "__main__":
demo.launch()