from streamlit_js_eval import streamlit_js_eval
import torchvision.transforms as transforms
import streamlit as st
from PIL import Image
import torch
import time
st.set_page_config(page_title="Invertable Steganography", layout="centered", page_icon="📷")
# model
class HiddenNetwork:
def __init__(self, public_key):
super().__init__()
self.public_key = public_key
def noise(self, x):
torch.manual_seed(self.public_key)
noise = torch.randn_like(x)
return noise
def forward(self, x):
return x - self.noise(x)
def backward(self, x):
return x + self.noise(x)
def load(encode_key=0, decode_key=0):
with st.spinner('Getting Neruons in Order ...'):
encode_model = HiddenNetwork(int(encode_key))
decode_model = HiddenNetwork(int(decode_key))
process = transforms.Compose([transforms.Resize((224, 224)), transforms.ToTensor()])
time.sleep(1)
return encode_model, decode_model, process
def main():
# Set Streamlit theme to dark mode
st.markdown(
"""
""",
unsafe_allow_html=True,
)
st.markdown("
📷 Invertable Steganography 📷
", unsafe_allow_html=True)
st.image("secret.png", use_column_width=True)
st.write(
"""
Invertible neural networks like FreiA and Glow are neural architectures designed for reversible data transformations.
They are often used in image steganography, allowing data to be encoded and perfectly reconstructed without any loss of
information. These networks utilize public keys as seeds, enhancing security and ensuring that only authorized parties can
access the hidden data within encoded images.
"""
)
# Create inputs
st.markdown("""---""")
input_image = st.file_uploader("Encode Image", type=["jpg", "jpeg", "png"], key="1")
col1, col2 = st.columns(2)
encode_key = col1.number_input("Encoding Key", value=42, key="2")
decode_key = col2.number_input("Decoding Key", value=42, key="3")
# core
col1, col2, col3, col4 = st.columns(4)
col1.write("Input")
col2.write("Encode")
col3.write("Decode Encode")
col4.write("Decode Input")
# columns
if input_image is not None:
encode_model, decode_model, process = load(encode_key, decode_key)
image = process(Image.open(input_image).convert("RGB"))
forward = encode_model.forward(image)
backward = decode_model.backward(forward)
backward_input = decode_model.backward(image)
with col1:
st.image(transforms.ToPILImage()(image), use_column_width=True)
transforms.ToPILImage()(image).save("tmp/image.png")
st.download_button(label='Download Image', data=open('tmp/image.png', 'rb').read(), file_name='image.png', mime='image/png', key="4")
with col2:
st.image(transforms.ToPILImage()(forward), use_column_width=True)
transforms.ToPILImage()(forward).save("tmp/forward.png")
st.download_button(label='Download Image', data=open('tmp/forward.png', 'rb').read(), file_name='forward.png', mime='image/png', key="5")
with col3:
st.image(transforms.ToPILImage()(backward), use_column_width=True)
transforms.ToPILImage()(backward).save("tmp/back.png")
st.download_button(label='Download Image', data=open('tmp/back.png', 'rb').read(), file_name='back.png', mime='image/png', key="6")
with col4:
st.image(transforms.ToPILImage()(backward_input), use_column_width=True)
transforms.ToPILImage()(backward_input).save("tmp/input.png")
st.download_button(label='Download Image', data=open('tmp/input.png', 'rb').read(), file_name='input.png', mime='image/png', key="7")
# Create a button to reset the interface page
st.markdown("""---""")
if st.button("Reset", use_container_width=True):
streamlit_js_eval(js_expressions="parent.window.location.reload()")
if __name__ == "__main__":
main()