import gradio as gr import time import numpy as np from PIL import Image import os def save_image(im, filename="saved_image.png"): """画像をファイルに保存する関数""" if im is not None and "composite" in im: # 合成画像(最終結果)を取得 composite = im["composite"] # numpy配列の場合はPIL Imageに変換 if isinstance(composite, np.ndarray): composite = Image.fromarray(composite) # 画像を保存 composite.save(filename) return f"画像が正常に {filename} として保存されました" else: return "保存する画像がないか、無効な画像形式です" # Gradio Blocksアプリケーションを作成(テーマをOceanに設定) with gr.Blocks(theme=gr.themes.Ocean()) as demo: gr.Markdown("# Image Editor Demo") with gr.Row(): with gr.Column(): # 1:1の縦横比でImageEditorコンポーネントを作成 im = gr.ImageEditor( type="numpy", # 画像はnumpy配列として処理される crop_size="1:1", # 正方形のトリミング比率を設定 label="画像エディタ" ) with gr.Column(): # プレビュー表示用のImageコンポーネントを作成 im_preview = gr.Image(label="プレビュー") # 各種イベントを追跡するカウンター with gr.Row(): n_upload = gr.Number(0, label="アップロードイベント数", step=1) n_change = gr.Number(0, label="変更イベント数", step=1) n_input = gr.Number(0, label="入力イベント数", step=1) # ファイル名入力と保存ボタンを追加 with gr.Row(): filename_input = gr.Textbox(value="my_drawing.png", label="ファイル名") save_btn = gr.Button("画像を保存", variant="primary") # 保存操作のステータスメッセージ save_status = gr.Textbox(label="保存ステータス", interactive=False) # イベントハンドラーを定義: # 画像がアップロードされたらアップロードカウンターを増加 im.upload(lambda x: x + 1, outputs=n_upload, inputs=n_upload) # 画像が変更されたら変更カウンターを増加(ユーザー入力または関数更新による) im.change(lambda x: x + 1, outputs=n_change, inputs=n_change) # ユーザーが画像を変更したら入力カウンターを増加 im.input(lambda x: x + 1, outputs=n_input, inputs=n_input) # 画像が変更されたらプレビューエリアに合成画像を表示 im.change(lambda im: im["composite"] if im and "composite" in im else None, outputs=im_preview, inputs=im, show_progress="hidden") # 保存ボタンクリックイベントを設定 save_btn.click( fn=save_image, inputs=[im, filename_input], outputs=save_status ) # このスクリプトが直接実行されたときにデモを起動 if __name__ == "__main__": demo.launch()