import gradio as gr from PIL import Image import os import cv2 import numpy as np def process_image(image_path): # 画像を読み込む image = Image.open(image_path) # 最大解像度を設定(1200x1900) max_width = 1900 max_height = 1200 # アスペクト比を保ちながらリサイズ width, height = image.size if width > max_width or height > max_height: # アスペクト比を保ったままリサイズ aspect_ratio = width / height if width > max_width: width = max_width height = int(width / aspect_ratio) if height > max_height: height = max_height width = int(height * aspect_ratio) image = image.resize((width, height), Image.LANCZOS) # RGBからBGRに変換(cv2はBGRを使用する) image = np.array(image) image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # 動画のフレーム数(30fpsで5秒分) fps = 30 duration = 5 total_frames = fps * duration # フレームリストを作成 frames = [] for _ in range(total_frames): frames.append(image) # 動画保存先の一時ファイルパス output_video_path = "/tmp/output_video.mp4" # 動画ファイルにフレームを保存 fourcc = cv2.VideoWriter_fourcc(*'mp4v') # MP4形式 height, width, _ = frames[0].shape video_writer = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height)) # フレームを動画に書き込む for frame in frames: video_writer.write(frame) video_writer.release() # 動画ファイルをGradioに返す return output_video_path class WebUI: def __init__(self): self.demo = gr.Blocks() def main(self, image_path): output_video = process_image(image_path) return output_video def launch(self, share): with self.demo: with gr.Row(): with gr.Column(): input_image = gr.Image(type='filepath') submit = gr.Button(value="Start") with gr.Row(): with gr.Column(): with gr.Tab("Output"): output_mp4 = gr.Video() submit.click(self.main, inputs=[input_image], outputs=[output_mp4]) self.demo.queue() self.demo.launch(share=share) if __name__ == "__main__": ui = WebUI() ui.launch(share=True)