import gradio as gr from PIL import Image, ImageEnhance, ImageFilter import numpy as np # 필터 추천에 따른 슬라이드바 값 설정 def set_preset_filter(preset): presets = { "자동": [0, 0, 0, 0, 0.25, 0, 0, 0, 0.16, 0, 0.06, 0], "따스한": [0.07, 0, 0, 0, 0.25, 0.16, 0, 0, 0.16, 0, 0.06, 0], "깨끗한": [0.02, 0, 0, 0, 0.25, 0, 0.04, 0, 0.21, 0, 0.06, 0], "흑백": [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], } return presets.get(preset, [0] * 12) # 필터 적용 함수 def apply_filters(image, *sliders): if image is None: return None pil_image = Image.fromarray(image) soft_glow, sepia, vintage, black_white, sharpen, warm_tone, cold_tone, film_grain, high_key, low_key, clarity, saturation = sliders if soft_glow > 0: glow = pil_image.filter(ImageFilter.GaussianBlur(radius=10)) pil_image = Image.blend(pil_image, glow, alpha=soft_glow) if black_white > 0: gray = pil_image.convert("L") pil_image = Image.blend(pil_image, gray.convert("RGB"), alpha=black_white) if sharpen > 0: enhancer = ImageEnhance.Sharpness(pil_image) pil_image = enhancer.enhance(1 + sharpen) if warm_tone > 0: r, g, b = pil_image.split() r = r.point(lambda i: i * (1 + warm_tone)) b = b.point(lambda i: i * (1 - warm_tone)) pil_image = Image.merge("RGB", (r, g, b)) if cold_tone > 0: r, g, b = pil_image.split() r = r.point(lambda i: i * (1 - cold_tone)) b = b.point(lambda i: i * (1 + cold_tone)) pil_image = Image.merge("RGB", (r, g, b)) if high_key > 0: enhancer = ImageEnhance.Brightness(pil_image) pil_image = enhancer.enhance(1 + high_key) if clarity > 0: enhancer = ImageEnhance.Contrast(pil_image) pil_image = enhancer.enhance(1 + clarity) return np.array(pil_image) # Gradio 인터페이스 with gr.Blocks() as app: gr.Markdown("## 고급 필터 조합기") # 첫 번째 행: 이미지 업로드 창 | 필터 적용 이미지 with gr.Row(): image_input = gr.Image(type="numpy", label="이미지 업로드", interactive=True) output_image = gr.Image(type="numpy", label="필터 적용 이미지") # 필터 초기화 버튼 with gr.Row(): reset_button = gr.Button("필터 초기화") # 두 번째 행: 필터 추천 with gr.Row(): preset_selector = gr.Radio( ["자동", "따스한", "깨끗한", "흑백"], label="필터 추천" ) # 세 번째 행: 필터 속성 슬라이드바 (1열 | 2열) with gr.Row(): with gr.Column(): sliders_left = [ gr.Slider(0, 1, value=0, step=0.01, label="Soft Glow (부드러운 빛)"), gr.Slider(0, 1, value=0, step=0.01, label="Sepia (세피아 톤)"), gr.Slider(0, 1, value=0, step=0.01, label="Vintage (빈티지 효과)"), gr.Slider(0, 1, value=0, step=0.01, label="Black & White (흑백)"), gr.Slider(0, 1, value=0, step=0.01, label="Sharpen (선명하게)"), gr.Slider(0, 1, value=0, step=0.01, label="Warm Tone (따뜻한 색조)"), ] with gr.Column(): sliders_right = [ gr.Slider(0, 1, value=0, step=0.01, label="Cold Tone (차가운 색조)"), gr.Slider(0, 1, value=0, step=0.01, label="Film Grain (필름 질감)"), gr.Slider(0, 1, value=0, step=0.01, label="High-Key (밝은 톤 강조)"), gr.Slider(0, 1, value=0, step=0.01, label="Low-Key (어두운 톤 강조)"), gr.Slider(0, 1, value=0, step=0.01, label="Clarity (선명도 강화)"), gr.Slider(0, 1, value=0, step=0.01, label="Saturation (채도)"), ] # 네 번째 행: 다운로드 형식과 버튼 with gr.Row(): download_format = gr.Radio(["JPG", "PNG"], label="다운로드 형식") download_button = gr.Button("다운로드") # 슬라이드바 연결 all_sliders = sliders_left + sliders_right for slider in all_sliders: slider.change( apply_filters, inputs=[image_input] + all_sliders, outputs=[output_image] ) # 필터 추천 선택 시 슬라이드바 업데이트 preset_selector.change( lambda preset: set_preset_filter(preset), inputs=[preset_selector], outputs=all_sliders ) # 이미지 삭제 시 필터 적용 이미지도 삭제 image_input.change( lambda img: None if img is None else img, inputs=[image_input], outputs=[output_image] ) # 다운로드 버튼 클릭 download_button.click( lambda img, fmt: f"filtered_image.{fmt.lower()}" if img is not None else None, inputs=[output_image, download_format], outputs=[] ) # 필터 초기화 버튼 클릭 reset_button.click( lambda img: [None] + [0] * len(all_sliders), inputs=[image_input], outputs=[output_image] + all_sliders ) if __name__ == "__main__": app.launch()