import streamlit as st
from langchain_core.messages import HumanMessage
from langchain_google_genai import ChatGoogleGenerativeAI
from streamlit_chat import message
from PIL import Image
import base64
import io
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import StreamlitChatMessageHistory
import os
# Streamlit app
def image():
st.title("Chat with Image")
key = os.environ.get("api_key")
st.markdown("""
""", unsafe_allow_html=True)
text1 = "Hello 👋, upload an image and ask questions related to it!"
animated = f'
{text1}
'
with st.chat_message("assistant").markdown(animated, unsafe_allow_html=True):
st.markdown(animated, unsafe_allow_html=True)
def process_image(uploaded_file):
# Display the uploaded image
image = Image.open(uploaded_file)
st.image(image, caption='Uploaded Image', use_column_width=True)
# Process the image and return the URL or other information
# For demonstration purposes, convert the image to base64 and return a data URL
buffered = io.BytesIO()
image.save(buffered, format="JPEG")
image_base64 = base64.b64encode(buffered.getvalue()).decode("utf-8")
image_url = f"data:image/jpeg;base64,{image_base64}"
return image_url
apiKey = key
llm = ChatGoogleGenerativeAI(model="gemini-pro-vision", google_api_key=apiKey)
image_url = None # Initialize image_url outside the if statement
with st.sidebar:
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
image_url = process_image(uploaded_file)
if 'messages' not in st.session_state:
st.session_state['messages'] = []
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
prompt = st.chat_input("Say something")
message = HumanMessage(
content=[
{
"type": "text",
"text": prompt,
}, # You can optionally provide text parts
{"type": "image_url", "image_url": image_url},
]
)
if prompt:
with st.chat_message("user").markdown(prompt):
st.session_state.messages.append(
{
"role": "user",
"content": prompt
}
)
spinner_html = """
"""
spinner_css = """
.dot-pulse {
position: relative;
left: -9999px;
width: 10px;
height: 10px;
border-radius: 5px;
background-color: #9880ff;
color: #9880ff;
box-shadow: 9999px 0 0 -5px;
animation: dot-pulse 1.5s infinite linear;
animation-delay: 0.25s;
}
.dot-pulse::before, .dot-pulse::after {
content: "";
display: inline-block;
position: absolute;
top: 0;
width: 10px;
height: 10px;
border-radius: 5px;
background-color: #9880ff;
color: #9880ff;
}
.dot-pulse::before {
box-shadow: 9984px 0 0 -5px;
animation: dot-pulse-before 1.5s infinite linear;
animation-delay: 0s;
}
.dot-pulse::after {
box-shadow: 10014px 0 0 -5px;
animation: dot-pulse-after 1.5s infinite linear;
animation-delay: 0.5s;
}
@keyframes dot-pulse-before {
0% {
box-shadow: 9984px 0 0 -5px;
}
30% {
box-shadow: 9984px 0 0 2px;
}
60%, 100% {
box-shadow: 9984px 0 0 -5px;
}
}
@keyframes dot-pulse {
0% {
box-shadow: 9999px 0 0 -5px;
}
30% {
box-shadow: 9999px 0 0 2px;
}
60%, 100% {
box-shadow: 9999px 0 0 -5px;
}
}
@keyframes dot-pulse-after {
0% {
box-shadow: 10014px 0 0 -5px;
}
30% {
box-shadow: 10014px 0 0 2px;
}
60%, 100% {
box-shadow: 10014px 0 0 -5px;
}
}
"""
st.markdown(f'', unsafe_allow_html=True)
st.markdown(spinner_html, unsafe_allow_html=True)
response = llm.invoke([message])
text_output = response.content
st.markdown('', unsafe_allow_html=True)
with st.chat_message("assistant").markdown(text_output):
st.session_state.messages.append(
{
"role": "assistant",
"content": text_output
}
)