# __init__.py from pathlib import Path from typing import Optional, Tuple, List from PIL import Image import streamlit as st import streamlit.components.v1 as components frontend_dir = (Path(__file__).parent / "frontend").absolute() _component_func = components.declare_component( "streamlit_copy_to_clipboard", path=str(frontend_dir) ) def st_copy_to_clipboard( image: Image.Image, button_coords: List[Tuple[Tuple[int, int], Tuple[int, int]]], text_list: List[str], before_copy_label: str = "📋", after_copy_label: str = "✅", key: Optional[str] = None, ): """ Streamlit component to copy text to clipboard with buttons over an image. Parameters ---------- image : PIL.Image The image over which the buttons will be placed. button_coords : List[Tuple[Tuple[int, int], Tuple[int, int]]] List of tuples, each containing top-left and bottom-right coordinates for buttons. text_list : List[str] List of texts to be copied to the clipboard. before_copy_label : str Label of the button before text is copied. after_copy_label : str Label of the button after text is copied. key : str or None An optional key that uniquely identifies the component. """ # Convert the PIL image to base64 for sending to frontend import base64 from io import BytesIO buffered = BytesIO() image.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode("utf-8") # Create the component component_value = _component_func( key=key, image=f"data:image/png;base64,{img_str}", button_coords=button_coords, text_list=text_list, before_copy_label=before_copy_label, after_copy_label=after_copy_label, ) return component_value def main(): st.write("## Example: Image with Copy Buttons") # Example image and button coordinates img = Image.new('RGB', (1080, 1080), color = 'white') button_coords = [((152, 130), (252, 180)), ((400, 500), (500, 550))] # List of top-left and bottom-right points texts = ["Copy text 1", "Copy text 2"] st_copy_to_clipboard(img, button_coords, texts) if __name__ == "__main__": main()