Spaces:
Sleeping
Sleeping
File size: 4,140 Bytes
90a5359 8343d7f f0ae214 8343d7f f0ae214 8343d7f 3f14974 f0ae214 fae1db2 f0ae214 8343d7f 3f14974 8343d7f f0ae214 3f14974 409a47c 3f14974 858a92e 3f14974 fae1db2 f0ae214 8343d7f f0ae214 8343d7f fae1db2 8343d7f fae1db2 f0ae214 8343d7f 3f14974 fae1db2 c7325c8 4cd9408 3f14974 8343d7f 3f14974 f0ae214 fae1db2 f0ae214 3f14974 f0ae214 fae1db2 f0ae214 3f14974 f0ae214 fae1db2 3f14974 f0ae214 fae1db2 f0ae214 fae1db2 3f14974 fae1db2 3f14974 fae1db2 f0ae214 fae1db2 3f14974 f0ae214 fae1db2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | import streamlit as st
from transformers import pipeline
from PIL import Image
import datetime
# --- PAGE CONFIG ---
st.set_page_config(page_title="SaaS Media Vault", layout="wide")
# Custom CSS to prevent layout shifting and "shaking"
st.markdown("""
<style>
.stColumn {
transition: none !important;
}
div[data-testid="stVerticalBlock"] > div {
animation: none !important;
}
</style>
""", unsafe_allow_html=True)
st.title("ποΈ SaaS Media Intelligence Vault")
st.markdown("Analyze, store, and **search** your media assets using AI-generated metadata.")
# --- INITIALIZE SESSION STATE ---
if "media_library" not in st.session_state:
st.session_state.media_library = []
# --- MODEL LOADING ---
@st.cache_resource
def load_models():
# CLIP for general categorization
classifier = pipeline("zero-shot-image-classification",
model="openai/clip-vit-base-patch32",
device=-1)
# BLIP for natural language description
captioner = pipeline("image-text-to-text",
model="Salesforce/blip-image-captioning-base",
device=-1)
return classifier, captioner
classifier, captioner = load_models()
# --- SIDEBAR: UPLOAD & SETTINGS ---
st.sidebar.header("π₯ Asset Management")
uploaded_file = st.sidebar.file_uploader("Add New Image", type=["jpg", "png", "jpeg"])
if uploaded_file:
if st.sidebar.button("Process & Index Asset"):
image = Image.open(uploaded_file)
with st.spinner("AI is indexing..."):
# 1. BLIP Description
prompt = "a photo of"
caption_out = captioner(image, text=prompt, max_new_tokens=30)
description = caption_out[0]['generated_text'].replace("a photo of ", "")
# 2. Internal Auto-Tagging (Replaces the manual keywords input)
# We use a broad set of categories to give the AI context without user input
auto_labels = ["object", "person", "place", "nature", "technology", "document"]
clip_out = classifier(image, candidate_labels=auto_labels)
top_label = clip_out[0]['label']
top_score = clip_out[0]['score']
# 3. SAVE TO ARRAY
asset_data = {
"id": f"{datetime.datetime.now().timestamp()}", # Unique ID to prevent UI jitter
"timestamp": datetime.datetime.now().strftime("%H:%M:%S"),
"image": image,
"description": description.lower(),
"tag": top_label.lower(),
"confidence": top_score
}
# Insert at the top
st.session_state.media_library.insert(0, asset_data)
st.sidebar.success("Asset Cataloged!")
# --- MAIN SECTION: SEARCH & RETRIEVAL ---
st.subheader("π Intelligent Retrieval")
search_query = st.text_input("Search the vault (e.g., 'flowers', 'tech', 'laptop')", "").lower()
# --- FILTER LOGIC ---
if search_query:
filtered_items = [
item for item in st.session_state.media_library
if search_query in item["description"] or search_query in item["tag"]
]
else:
filtered_items = st.session_state.media_library
# --- DISPLAY VAULT ---
st.write(f"Showing **{len(filtered_items)}** assets")
if not filtered_items:
st.info("No matching assets found in the vault.")
else:
# Using a container with a fixed key helps Streamlit manage the DOM state better
for item in filtered_items:
with st.container():
col1, col2 = st.columns([1, 3])
with col1:
st.image(item["image"], use_container_width=True)
with col2:
st.write(f"**π Logged:** {item['timestamp']}")
st.info(f"**AI Description:** {item['description'].capitalize()}")
st.write(f"**π·οΈ Type:** `{item['tag']}` ({round(item['confidence']*100, 1)}%)")
st.divider()
# --- CLEAR UTILITY ---
if st.sidebar.button("ποΈ Wipe Vault Memory"):
st.session_state.media_library = []
st.rerun() |