Spaces:
Running
Running
| # Copyright 2023-2025 Marigold Team, ETH Zürich. All rights reserved. | |
| # This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. | |
| # See https://creativecommons.org/licenses/by-sa/4.0/ for details. | |
| # -------------------------------------------------------------------------- | |
| # DualVision is a Gradio template app for image processing. It was developed | |
| # to support the Marigold project. If you find this code useful, we kindly | |
| # ask you to cite our most relevant papers. | |
| # More information about Marigold: | |
| # https://marigoldmonodepth.github.io | |
| # https://marigoldcomputervision.github.io | |
| # Efficient inference pipelines are now part of diffusers: | |
| # https://huggingface.co/docs/diffusers/using-diffusers/marigold_usage | |
| # https://huggingface.co/docs/diffusers/api/pipelines/marigold | |
| # Examples of trained models and live demos: | |
| # https://huggingface.co/prs-eth | |
| # Related projects: | |
| # https://marigolddepthcompletion.github.io/ | |
| # https://rollingdepth.github.io/ | |
| # Citation (BibTeX): | |
| # https://github.com/prs-eth/Marigold#-citation | |
| # https://github.com/prs-eth/Marigold-DC#-citation | |
| # https://github.com/prs-eth/rollingdepth#-citation | |
| # -------------------------------------------------------------------------- | |
| import gradio | |
| import gradio.component_meta as _component_meta | |
| def _noop_create_or_modify_pyi(*args, **kwargs): | |
| return None | |
| _component_meta.create_or_modify_pyi = _noop_create_or_modify_pyi | |
| import numpy as np | |
| import PIL.Image | |
| from concurrent.futures import ThreadPoolExecutor | |
| from pathlib import Path | |
| from urllib.parse import quote, urlparse | |
| from gradio import FileData, image_utils, processing_utils, utils, wasm_utils | |
| from gradio.components.gallery import ( | |
| GalleryData, | |
| GalleryImage, | |
| GalleryMediaType, | |
| CaptionedGalleryMediaType, | |
| GalleryVideo, | |
| ) | |
| from gradio_client import utils as client_utils | |
| from gradio_client.utils import is_http_url_like | |
| from gradio.data_classes import ImageData | |
| class Gallery(gradio.Gallery): | |
| def postprocess( | |
| self, | |
| value: list[GalleryMediaType | CaptionedGalleryMediaType] | None, | |
| ) -> GalleryData: | |
| """ | |
| Parameters: | |
| value: Expects the function to return a `list` of images or videos, or `list` of (media, `str` caption) tuples. Each image can be a `str` file path, a `numpy` array, or a `PIL.Image` object. Each video can be a `str` file path. | |
| Returns: | |
| a list of images or videos, or list of (media, caption) tuples | |
| """ | |
| if value is None: | |
| return GalleryData(root=[]) | |
| if isinstance(value, str): | |
| raise ValueError( | |
| "The `value` passed into `gr.Gallery` must be a list of images or videos, or list of (media, caption) tuples." | |
| ) | |
| output = [] | |
| def _save(img): | |
| url = None | |
| caption = None | |
| orig_name = None | |
| mime_type = None | |
| if isinstance(img, (tuple, list)): | |
| img, caption = img | |
| if isinstance(img, np.ndarray): | |
| file = processing_utils.save_img_array_to_cache( | |
| img, cache_dir=self.GRADIO_CACHE, format=self.format | |
| ) | |
| file_path = str(utils.abspath(file)) | |
| elif isinstance(img, PIL.Image.Image): | |
| format = ( | |
| "png" if img.mode == "I;16" else self.format | |
| ) # Patch 1: change format based on the inbound dtype | |
| file = processing_utils.save_pil_to_cache( | |
| img, cache_dir=self.GRADIO_CACHE, format=format | |
| ) | |
| file_path = str(utils.abspath(file)) | |
| elif isinstance(img, str): | |
| mime_type = client_utils.get_mimetype(img) | |
| if img.lower().endswith(".svg"): | |
| svg_content = image_utils.extract_svg_content(img) | |
| orig_name = Path(img).name | |
| url = f"data:image/svg+xml,{quote(svg_content)}" | |
| file_path = None | |
| elif is_http_url_like(img): | |
| url = img | |
| orig_name = Path(urlparse(img).path).name | |
| file_path = img | |
| else: | |
| url = None | |
| orig_name = Path(img).name | |
| file_path = img | |
| elif isinstance(img, Path): | |
| file_path = str(img) | |
| orig_name = img.name | |
| mime_type = client_utils.get_mimetype(file_path) | |
| else: | |
| raise ValueError(f"Cannot process type as image: {type(img)}") | |
| if mime_type is not None and "video" in mime_type: | |
| return GalleryVideo( | |
| video=FileData( | |
| path=file_path, # type: ignore | |
| url=url, | |
| orig_name=orig_name, | |
| mime_type=mime_type, | |
| ), | |
| caption=caption, | |
| ) | |
| else: | |
| return GalleryImage( | |
| image=ImageData( | |
| path=file_path, | |
| url=url, | |
| orig_name=orig_name, | |
| mime_type=mime_type, | |
| ), | |
| caption=caption, | |
| ) | |
| if wasm_utils.IS_WASM: | |
| for img in value: | |
| output.append(_save(img)) | |
| else: | |
| with ThreadPoolExecutor() as executor: | |
| for o in executor.map(_save, value): | |
| output.append(o) | |
| return GalleryData(root=output) | |