| import gradio as gr |
| from PIL import Image, ImageEnhance, ImageOps, ImageFilter |
| import io |
| import base64 |
| import tempfile |
| import os |
|
|
| def image_to_base64(img): |
| """ |
| PIL ์ด๋ฏธ์ง๋ฅผ base64 ์ธ์ฝ๋ฉ๋ ๋ฌธ์์ด๋ก ๋ณํํฉ๋๋ค. |
| """ |
| buffered = io.BytesIO() |
| img.save(buffered, format="JPEG") |
| img_bytes = buffered.getvalue() |
| img_base64 = base64.b64encode(img_bytes).decode() |
| return img_base64 |
|
|
| def transform_image(image, contrast, brightness, blur): |
| """ |
| ์ด๋ฏธ์ง๋ฅผ ํ๋ฐฑ์ผ๋ก ๋ณํํ๊ณ , ์ฌ์ฉ์๊ฐ ์กฐ์ ํ ๋๋น, ๋ฐ๊ธฐ, ํ๋ฆผ ํจ๊ณผ๋ฅผ ์ ์ฉํฉ๋๋ค. |
| """ |
| |
| bw_image = ImageOps.grayscale(image) |
| |
| |
| enhancer = ImageEnhance.Contrast(bw_image) |
| bw_image = enhancer.enhance(contrast) |
| |
| |
| enhancer = ImageEnhance.Brightness(bw_image) |
| bw_image = enhancer.enhance(brightness) |
| |
| |
| bw_image = bw_image.filter(ImageFilter.GaussianBlur(radius=blur)) |
| |
| return bw_image |
|
|
| def generate_comparison_html(original_base64, transformed_base64): |
| """ |
| ๋ณํ๋ ์ด๋ฏธ์ง์ ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ๋น๊ตํ ์ ์๋ ์ํ ์ฌ๋ผ์ด๋ HTML์ ์์ฑํฉ๋๋ค. |
| ๋ณํ๋ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ์ฌ๋ผ์ด๋๋ฅผ ์์ง์ฌ ์๋ณธ ์ด๋ฏธ์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. |
| """ |
| html = f""" |
| <div style="position: relative; width: 100%; max-width: 600px; margin: auto;"> |
| <!-- ๋ณํ๋ ์ด๋ฏธ์ง (๋ฐฐ๊ฒฝ) --> |
| <img src="data:image/jpeg;base64,{transformed_base64}" style="width: 100%; display: block;"> |
| |
| <!-- ์๋ณธ ์ด๋ฏธ์ง (์ค๋ฒ๋ ์ด) --> |
| <div id="overlay" style="position: absolute; top:0; left:0; width:50%; overflow: hidden; height:100%;"> |
| <img src="data:image/jpeg;base64,{original_base64}" style="width: 100%;"> |
| </div> |
| |
| <!-- ์ฌ๋ผ์ด๋ --> |
| <input type="range" min="0" max="100" value="50" |
| oninput="document.getElementById('overlay').style.width = this.value + '%';" |
| style=" |
| position: absolute; |
| bottom: 10px; |
| left: 50%; |
| transform: translateX(-50%); |
| width: 80%; |
| -webkit-appearance: none; |
| background: transparent; |
| "> |
| |
| <!-- ์ฌ๋ผ์ด๋ ๋ ์ด๋ธ --> |
| <div style="text-align: center; margin-top: 10px;"> |
| <span>๋ณํ ํ</span> <span style="float: right;">๋ณํ ์ </span> |
| </div> |
| |
| <!-- ์ฌ๋ผ์ด๋ ์คํ์ผ๋ง --> |
| <style> |
| input[type=range] {{ |
| -webkit-appearance: none; |
| width: 100%; |
| height: 5px; |
| background: #ddd; |
| outline: none; |
| opacity: 0.7; |
| -webkit-transition: .2s; |
| transition: opacity .2s; |
| }} |
| |
| input[type=range]::-webkit-slider-thumb {{ |
| -webkit-appearance: none; |
| appearance: none; |
| width: 15px; |
| height: 15px; |
| background: #4CAF50; |
| cursor: pointer; |
| border-radius: 50%; |
| }} |
| |
| input[type=range]::-moz-range-thumb {{ |
| width: 15px; |
| height: 15px; |
| background: #4CAF50; |
| cursor: pointer; |
| border-radius: 50%; |
| }} |
| </style> |
| </div> |
| """ |
| return html |
|
|
| def process_image(image, contrast, brightness, blur): |
| """ |
| ์ฌ์ฉ์๊ฐ ์
๋ก๋ํ ์ด๋ฏธ์ง๋ฅผ ๋ณํํ๊ณ , ๋น๊ต ์ฌ๋ผ์ด๋์ ๋ค์ด๋ก๋ ๋งํฌ๋ฅผ ์์ฑํฉ๋๋ค. |
| """ |
| if image is None: |
| return "์ด๋ฏธ์ง๊ฐ ์
๋ก๋๋์ง ์์์ต๋๋ค.", None |
|
|
| |
| transformed = transform_image(image, contrast, brightness, blur) |
| |
| |
| original_base64 = image_to_base64(image) |
| transformed_base64 = image_to_base64(transformed) |
| |
| |
| comparison_html = generate_comparison_html(original_base64, transformed_base64) |
| |
| |
| with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False, prefix="transformed_", dir="/tmp") as tmp_file: |
| transformed.save(tmp_file, format="JPEG") |
| tmp_file_path = tmp_file.name |
| |
| return comparison_html, tmp_file_path |
|
|
| with gr.Blocks() as demo: |
| gr.Markdown("## ๐ธ ๋ถ์๊ธฐ ์๋ ํ๋ฐฑ ์ฌ์ง ๋ณํ๊ธฐ") |
| gr.Markdown("์๋ณธ ์ด๋ฏธ์ง์ ๋ณํ๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ๋ผ์ด๋๋ก ๋น๊ตํ๊ณ , ๋ณํ๋ ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค.") |
| |
| with gr.Row(): |
| with gr.Column(): |
| input_image = gr.Image(type="pil", label="๐ฅ ์๋ณธ ์ด๋ฏธ์ง ์
๋ก๋") |
| contrast_slider = gr.Slider( |
| minimum=0.5, |
| maximum=3.0, |
| step=0.1, |
| value=1.5, |
| label="๐ ๋๋น ์กฐ์ " |
| ) |
| brightness_slider = gr.Slider( |
| minimum=0.5, |
| maximum=3.0, |
| step=0.1, |
| value=0.9, |
| label="๐ก ๋ฐ๊ธฐ ์กฐ์ " |
| ) |
| blur_slider = gr.Slider( |
| minimum=0, |
| maximum=5, |
| step=0.5, |
| value=1, |
| label="๐ซ๏ธ ํ๋ฆผ ํจ๊ณผ" |
| ) |
| convert_button = gr.Button("๐ ๋ณํํ๊ธฐ") |
| with gr.Column(): |
| comparison = gr.HTML(label="๐ ๋ณํ ์ ํ ๋น๊ต") |
| download_link = gr.File(label="โฌ๏ธ JPG๋ก ๋ค์ด๋ก๋") |
| |
| convert_button.click( |
| fn=process_image, |
| inputs=[input_image, contrast_slider, brightness_slider, blur_slider], |
| outputs=[comparison, download_link] |
| ) |
| |
| gr.Markdown("ยฉ๏ธ 2024 ๋ถ์๊ธฐ ์๋ ํ๋ฐฑ ์ฌ์ง ๋ณํ๊ธฐ by OpenAI") |
|
|
| demo.launch() |
|
|