test1229 / app.py
CSB261's picture
Update app.py
93e3a29 verified
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)
# ์ด๋ฏธ์ง€๋ฅผ base64๋กœ ๋ณ€ํ™˜
original_base64 = image_to_base64(image)
transformed_base64 = image_to_base64(transformed)
# ๋น„๊ต ์Šฌ๋ผ์ด๋“œ HTML ์ƒ์„ฑ
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()