import streamlit as st
# تمت إزالة استيراد components
# import streamlit.components.v1 as components # لاستقبال الرسائل
from PIL import Image
import torch
from torchvision import transforms
from transformers import AutoModelForImageSegmentation
import io
import os
import requests
from io import BytesIO
# --- 1. إعدادات الصفحة (تبقى في الأعلى) ---
st.set_page_config(
page_title="SkyData - Background Removal",
layout="wide"
)
# --- <<< إزالة كاملة لخطوة المصادقة والتحقق من النطاق ---
# تهيئة متغير "المصادقة" في حالة الجلسة
if 'authenticated' not in st.session_state:
# **التعديل هنا:** تعيين القيمة إلى True بشكل افتراضي لتجاوز التحقق
st.session_state.authenticated = True
# --- <<< هذا هو الجزء الذي تم تعديله (تمت إزالته) ---
# كود HTML/JavaScript الذي سيتم حقنه في Streamlit
# auth_listener_html = """
#
# """
# --- <<< نهاية الجزء الذي تم تعديله (تمت إزالته) ---
# تشغيل "المستمع" كعنصر HTML غير مرئي (تمت إزالته)
# auth_result = components.html(auth_listener_html, height=0, width=0)
# (الكود الذي أصلحناه سابقاً - تمت إزالته لعدم الحاجة)
# if auth_result and isinstance(auth_result, dict) and auth_result.get("authenticated") == True:
# st.session_state.authenticated = True
# --- نهاية خطوة المصادقة (تمت إزالة الأجزاء غير الضرورية) ---
# --- التحقق الرئيسي: لا تقم بتشغيل أي شيء إلا بعد المصادقة ---
# **تم ترك هذا التحقق، لكن بما أن القيمة هي True افتراضياً، سيتم تشغيل التطبيق**
if st.session_state.authenticated:
# --- 2. كود التصميم (CSS) ---
CUSTOM_CSS = """
"""
st.markdown(CUSTOM_CSS, unsafe_allow_html=True)
# --- 3. قاموس الترجمة ---
localization = {
'en': {
'brand_title': "", 'lang_select': "Select Language", 'input_method': "Select Input Method",
'tab_upload': "Image Upload", 'tab_url': "URL Input", 'tab_file': "File Output",
'upload_prompt': "Upload an image", 'upload_prompt_file': "Upload an image for file output",
'url_prompt': "Paste an image URL", 'processed_caption': "Processed Image",
'download_button': "Download PNG", 'error_fetching': "Error fetching image from URL:",
'error_processing': "Error processing image:", 'generic_error': "An error occurred:",
'page_title': "SkyData - Background Removal", 'spinner_text': "Processing image, please wait...",
},
'ar': {
'brand_title': "", 'lang_select': "اختر اللغة", 'input_method': "اختر طريقة الإدخال",
'tab_upload': "رفع صورة", 'tab_url': "رابط صورة", 'tab_file': "تصدير ملف",
'upload_prompt': "ارفع صورة", 'upload_prompt_file': "ارفع صورة لتصدير الملف",
'url_prompt': "الصق رابط الصورة", 'processed_caption': "الصورة المعالجة",
'download_button': "تحميل بصيغة PNG", 'error_fetching': "خطأ في جلب الصورة من الرابط:",
'error_processing': "خطأ في معالجة الصورة:", 'generic_error': "حدث خطأ:",
'page_title': "SkyData - أداة إزالة الخلفية", 'spinner_text': "جاري معالجة الصورة، يرجى الانتظار...",
}
}
# --- 4. تحميل النموذج ---
torch.set_float32_matmul_precision(["high", "highest"][0])
use_cuda = torch.cuda.is_available()
device = "cuda" if use_cuda else "cpu"
@st.cache_resource
def load_model():
model = AutoModelForImageSegmentation.from_pretrained("ZhengPeng7/BiRefNet", trust_remote_code=True)
model.to(device)
if use_cuda:
model = model.half()
return model
birefnet = load_model()
transform_image = transforms.Compose([
transforms.Resize((1024, 1024)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
# --- 5. دالة المعالجة الرئيسية ---
@st.cache_data
def process(image):
image_size = image.size
input_images = transform_image(image).unsqueeze(0).to(device)
if use_cuda:
input_images = input_images.half()
with torch.no_grad():
preds = birefnet(input_images)[-1].sigmoid().cpu()
pred = preds[0].squeeze()
pred_pil = transforms.ToPILImage()(pred)
mask = pred_pil.resize(image_size)
image.putalpha(mask)
img_bytes = io.BytesIO()
image.save(img_bytes, format="PNG")
img_bytes = img_bytes.getvalue()
return image, img_bytes
# --- 6. واجهة التطبيق (Sidebar) ---
lang_choice = st.sidebar.radio(
label="Select Language / اختر اللغة",
options=["English", "العربية"],
horizontal=True
)
lang_code = 'ar' if lang_choice == 'العربية' else 'en'
loc = localization[lang_code]
# --- 7. واجهة التطبيق الرئيسية (Main App) ---
LOGO_URL = "https://i.ibb.co/v4vwvcGq/skydatafull.webp"
col1, col2 = st.columns([1, 6])
with col1:
st.image(LOGO_URL, width=80)
with col2:
st.title(loc['page_title'])
st.sidebar.title(loc['brand_title'])
selected_tab = st.sidebar.radio(loc['input_method'], [loc['tab_upload'], loc['tab_url'], loc['tab_file']])
# --- 8. منطق التبويبات ---
if selected_tab == loc['tab_upload']:
uploaded_file = st.file_uploader(loc['upload_prompt'], type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
try:
image = Image.open(uploaded_file).convert("RGB")
with st.spinner(loc['spinner_text']):
processed_image, file_bytes = process(image)
st.image(processed_image, caption=loc['processed_caption'])
st.download_button(
label=loc['download_button'], data=file_bytes,
file_name=f"{uploaded_file.name.rsplit('.', 1)[0]}.png", mime="image/png",
)
except Exception as e:
st.error(f"{loc['generic_error']} {e}")
elif selected_tab == loc['tab_url']:
image_url = st.text_input(loc['url_prompt'])
if image_url:
try:
response = requests.get(image_url, stream=True)
response.raise_for_status()
image = Image.open(BytesIO(response.content)).convert("RGB")
with st.spinner(loc['spinner_text']):
processed_image, file_bytes = process(image)
st.image(processed_image, caption=loc['processed_caption'])
try:
file_name = image_url.split('/')[-1].rsplit('.', 1)[0] + ".png"
except Exception:
file_name = "processed_image.png"
st.download_button(
label=loc['download_button'], data=file_bytes,
file_name=file_name, mime="image/png",
)
except requests.exceptions.RequestException as e:
st.error(f"{loc['error_fetching']} {e}")
except Exception as e:
st.error(f"{loc['error_processing']} {e}")
elif selected_tab == loc['tab_file']:
uploaded_file = st.file_uploader(loc['upload_prompt_file'], type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
try:
image = Image.open(uploaded_file).convert("RGB")
with st.spinner(loc['spinner_text']):
processed_image, file_bytes = process(image)
st.image(processed_image, caption=loc['processed_caption'])
st.download_button(
label=loc['download_button'], data=file_bytes,
file_name=f"{uploaded_file.name.rsplit('.', 1)[0]}.png", mime="image/png",
)
except Exception as e:
st.error(f"{loc['generic_error']} {e}")
# --- إذا فشلت المصادقة ---
# **تمت إزالة الكود الذي يعرض رسالة "الوصول مرفوض"**
else:
pass
# st.error("🔒 الوصول مرفوض.")
# st.error("لا يمكن تشغيل هذه الأداة إلا من خلال النطاق المعتمد: https://www.skydata.kozow.com/")
# st.warning("Access Denied. This tool can only be run when embedded on https://www.skydata.kozow.com/")