SecureWatermark / app.py
fantos's picture
Update app.py
d5eb308 verified
import gradio as gr
from utils import WatermarkProcessor
import json
import tempfile
import os
from datetime import datetime
import cv2
from PIL import Image
import numpy as np
import logging
# ๋กœ๊น… ์„ค์ • (๋””๋ฒ„๊ทธ ์ •๋ณด ์ถœ๋ ฅ)
logging.basicConfig(level=logging.DEBUG)
class WatermarkGUI:
def __init__(self):
self.processor = WatermarkProcessor()
self.create_interface()
def process_watermark(self, image, watermark_text, author, purpose, opacity):
"""๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์›Œํ„ฐ๋งˆํฌ๋ฅผ ์ด๋ฏธ์ง€์— ์ถ”๊ฐ€"""
if image is None or watermark_text.strip() == "":
return None, "์ด๋ฏธ์ง€์™€ ์›Œํ„ฐ๋งˆํฌ ํ…์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•ด์ฃผ์„ธ์š”."
metadata = {
"author": author,
"purpose": purpose,
"opacity": opacity
}
# ์ž„์‹œ ์ด๋ฏธ์ง€ ์ €์žฅ
temp_path = tempfile.mktemp(suffix='.png')
try:
Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)).save(temp_path)
logging.debug("์ž„์‹œ ์ด๋ฏธ์ง€ ์ €์žฅ ์™„๋ฃŒ: %s", temp_path)
except Exception as e:
logging.error("์ž„์‹œ ์ด๋ฏธ์ง€ ์ €์žฅ ์ค‘ ์˜ค๋ฅ˜: %s", e)
return None, f"์ด๋ฏธ์ง€ ์ €์žฅ ์˜ค๋ฅ˜: {e}"
# ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€
result_path, message = self.processor.encode(temp_path, watermark_text, metadata)
logging.debug("์›Œํ„ฐ๋งˆํฌ ์ธ์ฝ”๋”ฉ ๊ฒฐ๊ณผ - result_path: %s, message: %s", result_path, message)
if "Error" in message:
os.remove(temp_path)
return None, message
# ํ’ˆ์งˆ ๋ณด๊ณ ์„œ ์ƒ์„ฑ
quality_report = self.processor.analyze_quality(temp_path, result_path)
try:
quality_data = json.loads(quality_report)
except Exception as e:
logging.error("ํ’ˆ์งˆ ๋ณด๊ณ ์„œ ํŒŒ์‹ฑ ์˜ค๋ฅ˜: %s", e)
quality_data = {"quality_score": "N/A", "psnr": "N/A", "histogram_similarity": 0, "modified_pixels": 0}
report = f"""
### Watermark Quality Report
- Quality Score: {quality_data.get('quality_score', 'N/A')}%
- PSNR: {quality_data.get('psnr', 'N/A')} dB
- Histogram Similarity: {quality_data.get('histogram_similarity', 0) * 100:.2f}%
- Modified Pixels: {quality_data.get('modified_pixels', 0):,}
### Metadata
- Author: {author}
- Purpose: {purpose}
- Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
os.remove(temp_path)
watermarked_image = cv2.imread(result_path)
if watermarked_image is None:
logging.error("์›Œํ„ฐ๋งˆํฌ๊ฐ€ ์ถ”๊ฐ€๋œ ์ด๋ฏธ์ง€ ๋กœ๋“œ ์‹คํŒจ: %s", result_path)
return None, "์›Œํ„ฐ๋งˆํฌ ์ด๋ฏธ์ง€ ๋กœ๋“œ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค."
return watermarked_image, report
def detect_watermark(self, image):
"""์›Œํ„ฐ๋งˆํฌ ๊ฒ€์ถœ ๋ฐ ์ถ”์ถœ"""
if image is None:
return "์ด๋ฏธ์ง€๋ฅผ ์ œ๊ณตํ•ด์ฃผ์„ธ์š”."
# ์ž„์‹œ ์ด๋ฏธ์ง€ ์ €์žฅ
temp_path = tempfile.mktemp(suffix='.png')
try:
Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)).save(temp_path)
logging.debug("์›Œํ„ฐ๋งˆํฌ ๊ฒ€์ถœ์šฉ ์ž„์‹œ ์ด๋ฏธ์ง€ ์ €์žฅ ์™„๋ฃŒ: %s", temp_path)
except Exception as e:
logging.error("๊ฒ€์ถœ์šฉ ์ด๋ฏธ์ง€ ์ €์žฅ ์ค‘ ์˜ค๋ฅ˜: %s", e)
return f"์ด๋ฏธ์ง€ ์ €์žฅ ์˜ค๋ฅ˜: {e}"
# ์›Œํ„ฐ๋งˆํฌ ์ถ”์ถœ
result = self.processor.decode(temp_path)
logging.debug("๋””์ฝ”๋“œ ๊ฒฐ๊ณผ: %s", result)
os.remove(temp_path)
try:
# JSON ํŒŒ์‹ฑ ์‹œ๋„
data = json.loads(result)
report = f"""
### Extracted Watermark
Text: {data.get('text', 'N/A')}
### Metadata
- Timestamp: {data.get('timestamp', 'N/A')}
- Author: {data.get('metadata', {}).get('author', 'N/A')}
- Purpose: {data.get('metadata', {}).get('purpose', 'N/A')}
"""
return report
except Exception as e:
logging.error("์›Œํ„ฐ๋งˆํฌ ๋””์ฝ”๋”ฉ ๊ฒฐ๊ณผ ํŒŒ์‹ฑ ์˜ค๋ฅ˜: %s", e)
# JSON ํŒŒ์‹ฑ ์‹คํŒจ ์‹œ, ์›๋ณธ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
return result
def create_interface(self):
"""Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ"""
with gr.Blocks(css="footer {visibility: hidden}") as self.interface:
gr.HTML(
"""<a href="https://visitorbadge.io/status?path=https%3A%2F%2Ffantos-SecureWatermark.hf.space">
<img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Ffantos-SecureWatermark.hf.space&countColor=%23263759" />
</a>"""
)
gr.Markdown(
"""# Enhanced Image Watermarking System
### Welcome to Secure Watermark - Advanced Image Protection System
๐Ÿ”’ **Key Features:**
- **Dual Watermarking Technology**: Supports both steganography and PNG metadata
- **Secure Encryption**: Military-grade encryption for watermark data
- **Quality Assurance**: Real-time quality analysis and reporting
- **Metadata Support**: Track authorship, purpose, and timestamps
- **Integrity Verification**: Hash-based image tampering detection
๐Ÿ’ก **Perfect for:**
- Copyright Protection
- Digital Asset Management
- Document Authentication
- Creative Work Protection
Try our system by uploading an image and adding your watermark below!
"""
)
with gr.Tabs():
# ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€ ํƒญ
with gr.Tab("Add Watermark"):
with gr.Row():
with gr.Column():
input_image = gr.Image(label="Input Image", type="numpy")
watermark_text = gr.Textbox(label="Watermark Text")
author = gr.Textbox(label="Author", placeholder="Enter author name")
purpose = gr.Textbox(label="Purpose", placeholder="Enter watermark purpose")
opacity = gr.Slider(minimum=0.1, maximum=1.0, value=0.3, label="Watermark Opacity")
with gr.Row():
process_btn = gr.Button("Add Watermark", variant="primary")
with gr.Column():
result_image = gr.Image(label="Watermarked Image")
quality_report = gr.Markdown(label="Quality Report")
# ์›Œํ„ฐ๋งˆํฌ ๊ฒ€์ถœ ํƒญ
with gr.Tab("Detect Watermark"):
with gr.Row():
detect_image = gr.Image(label="Input Image", type="numpy")
detect_result = gr.Markdown(label="Detected Watermark")
detect_btn = gr.Button("Detect Watermark")
# ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์—ฐ๊ฒฐ
process_btn.click(
fn=self.process_watermark,
inputs=[input_image, watermark_text, author, purpose, opacity],
outputs=[result_image, quality_report]
)
detect_btn.click(
fn=self.detect_watermark,
inputs=[detect_image],
outputs=detect_result
)
def launch(self, *args, **kwargs):
"""์ธํ„ฐํŽ˜์ด์Šค ์‹คํ–‰"""
self.interface.launch(*args, **kwargs)
if __name__ == "__main__":
app = WatermarkGUI()
app.launch()