diff --git a/.streamlit/config.toml b/.streamlit/config.toml
new file mode 100644
index 0000000..887b8fd
--- /dev/null
+++ b/.streamlit/config.toml
@@ -0,0 +1,5 @@
+[theme]
+primaryColor="#ffffff"
+backgroundColor="#181d27"
+secondaryBackgroundColor = "#2c374d"
+textColor = "#ffbf00"
\ No newline at end of file
diff --git a/docs/app.py b/docs/app.py
new file mode 100644
index 0000000..6dd62bd
--- /dev/null
+++ b/docs/app.py
@@ -0,0 +1,108 @@
+import streamlit as st
+from image_cipher import ImageCipher
+import tempfile
+import os
+
+
+def save_uploaded_file_to_temp(uploaded_file):
+ temp_dir = tempfile.mkdtemp()
+ temp_file_path = os.path.join(temp_dir, uploaded_file.name)
+ with open(temp_file_path, "wb") as f:
+ f.write(uploaded_file.getbuffer())
+ return temp_file_path
+
+
+def encrypt_image(image_path, message, encrypt):
+ cipher = ImageCipher()
+ encoded_image_path = cipher.encode(image_path, message, encrypt=encrypt)
+ return encoded_image_path, cipher.key
+
+
+def decrypt_image(image_path, key):
+ cipher = ImageCipher()
+ decoded_message = cipher.decode(image_path, key)
+ return decoded_message
+
+
+def main():
+ st.sidebar.image("docs/assets/image1.png", use_column_width=True)
+ with open("docs/css/styles.css") as f:
+ st.markdown(f"", unsafe_allow_html=True)
+ st.sidebar.markdown(
+ """\
+ """,
+ unsafe_allow_html=True,
+ )
+ st.title("Image Cipher")
+ app_mode = st.sidebar.radio(
+ "Choose the app mode", ["Encrypt", "Decrypt", "About Us"]
+ )
+
+ if app_mode == "Encrypt":
+ st.header("Encrypt Image")
+ uploaded_image = st.file_uploader(
+ "Choose an image...", type=["png", "jpg", "jpeg"]
+ )
+ message = st.text_area("Enter your message")
+ use_encryption = st.checkbox("Use Encryption")
+
+ if st.button("Encrypt"):
+ if uploaded_image and message:
+ temp_image_path = save_uploaded_file_to_temp(uploaded_image)
+ encoded_image_path, key = encrypt_image(
+ temp_image_path, message, use_encryption
+ )
+ if use_encryption:
+ st.markdown("### Encryption Key:")
+ st.markdown(f"```\n{key.decode()}\n```")
+ with open(encoded_image_path, "rb") as file:
+ st.download_button(
+ "Download Encrypted Image",
+ file,
+ file_name="encrypted_image.png",
+ )
+ st.image(encoded_image_path, caption="Encrypted Image")
+ else:
+ st.error(
+ "Please upload an image and enter a message\
+ to encrypt."
+ )
+
+ elif app_mode == "Decrypt":
+ st.header("Decrypt Image")
+ uploaded_image = st.file_uploader(
+ "Choose an image...", type=["png", "jpg", "jpeg"]
+ )
+ key = st.text_input("Enter key (if any)")
+
+ if st.button("Decrypt"):
+ try:
+ if uploaded_image:
+ temp_path = save_uploaded_file_to_temp(uploaded_image)
+ decrypted_message = decrypt_image(temp_path, key)
+ st.text_area(
+ "Decrypted Message",
+ value=decrypted_message,
+ height=200
+ )
+
+ else:
+ st.error("Please upload an image to decrypt.")
+
+ except Exception as e:
+ st.error(e)
+
+ elif app_mode == "About Us":
+ st.header("About Us")
+ st.markdown(
+ "This project is developed by
- [Abdul Samad]\
+ (https://github.com/samadpls/)
\
+ - [Maira Usman](https://github.com/Myrausman/)
\
+
",
+ unsafe_allow_html=True,
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/docs/css/styles.css b/docs/css/styles.css
index 73997dd..f652f44 100644
--- a/docs/css/styles.css
+++ b/docs/css/styles.css
@@ -1,66 +1,97 @@
+/* Main container */
body {
- display: flex;
- font-family: Arial, sans-serif;
- margin: 0;
- padding: 0;
+ background-color: #181d27;
+ color: #ffbf00;
}
-.sidebar {
- width: 200px;
- background-color: #2c3e50;
- color: white;
- padding: 20px;
+/* Sidebar */
+.css-1d391kg {
+ background-color: #4f535a;
}
-.sidebar .logo {
- text-align: center;
+.css-1lcbmhc, .css-1d2azem {
+ color: #ffbf00;
}
-.sidebar nav ul {
- list-style-type: none;
- padding: 0;
+.css-1v8qudd {
+ background-color: #2c374d;
+ color: #ffbf00;
}
-.sidebar nav ul li {
- margin: 20px 0;
+/* Header */
+.css-1siy2j7 {
+ color: #ffbf00;
}
-.sidebar nav ul li a {
- color: white;
- text-decoration: none;
+/* Radio buttons and text input */
+.css-1ex6qaa {
+ background-color: #2c374d;
+ color: #ffbf00;
}
-.content {
- flex: 1;
- padding: 20px;
+.css-1ex6qaa input[type="radio"] {
+ background-color: #2c374d;
+ color: #ffbf00;
}
-#encrypt-section, #decrypt-section, #about-section {
- max-width: 600px;
- margin: 0 auto;
+.css-1ex6qaa input[type="text"] {
+ background-color: #2c374d;
+ color: #ffbf00;
}
-input[type="file"], input[type="text"], textarea {
- display: block;
- width: 100%;
- margin-bottom: 20px;
+.css-1ex6qaa textarea {
+ background-color: #2c374d;
+ color: #ffbf00;
}
-button {
- padding: 10px 20px;
- background-color: #2980b9;
- color: white;
- border: none;
- cursor: pointer;
+/* Buttons */
+.css-1df45cr, .css-1f1iwnp, .css-1ktajzc {
+ background-color: #152544;
+ color: #ffbf00;
}
-button:hover {
- background-color: #3498db;
+.css-1df45cr:hover, .css-1f1iwnp:hover, .css-1ktajzc:hover {
+ background-color: #152544;
+ color: #ffffff;
}
-.logo {
- margin-bottom: 1rem; /* Change to a smaller value */
+
+/* Download button */
+.css-10trblm {
+ background-color: #152544;
+ color: #ffbf00;
+}
+
+.css-10trblm:hover {
+ background-color: #152544;
+ color: #ffffff;
+}
+
+/* Image */
+.css-11v1u3b img {
+ border: 2px solid #ffbf00;
+}
+
+/* Text */
+.css-qrbaxs p {
+ color: #ffbf00;
+}
+
+/* Error messages */
+.css-19hj99j {
+ background-color: #2c374d;
+ color: #ffbf00;
+}
+
+/* Markdown */
+.css-1uix8eu h1, .css-1uix8eu h2, .css-1uix8eu h3, .css-1uix8eu h4, .css-1uix8eu h5, .css-1uix8eu h6, .css-1uix8eu p {
+ color: #ffbf00;
+}
+
+/* Links */
+a {
+ color: #ffbf00;
}
-.nav {
- margin-top: 0; /* Ensure no extra margin above the nav */
+a:hover {
+ color: #ffffff;
}
diff --git a/docs/decrypt.html b/docs/decrypt.html
deleted file mode 100644
index 36eaea8..0000000
--- a/docs/decrypt.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
- Decrypt Image
-
-
-
-
-
-
Decrypt Image
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/index.html b/docs/index.html
deleted file mode 100644
index bc66e56..0000000
--- a/docs/index.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
- Image Cipher
-
-
-
-
-
-
-
-
-
-
-
-
Encrypt Image
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Decrypt Image
-
-
-
-
-
-
-
-
-
-
-
-
-
About Us
-
This is the about us section.
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/jss/script.js b/docs/jss/script.js
deleted file mode 100644
index 28c2ded..0000000
--- a/docs/jss/script.js
+++ /dev/null
@@ -1,137 +0,0 @@
-async function main() {
- console.log("Loading pyodide.");
- window.pyodide = await loadPyodide();
- console.log("Loading imagcipher...");
- await pyodide.loadPackage("micropip");
- const pip = pyodide.pyimport("micropip");
- await pip.install("imagecipher", { headers: { pragma: "no-cache", "cache-control": "no-cache" } });
-}
-
-main();
-
-function showSection(id) {
- const sections = ['encrypt-section', 'decrypt-section', 'about-section'];
- sections.forEach(section => {
- document.getElementById(section).style.display = section === id ? 'block' : 'none';
- });
-}
-
-document.addEventListener('DOMContentLoaded', (event) => {
- document.getElementById('encrypt-link').addEventListener('click', (event) => {
- event.preventDefault();
- showSection('encrypt-section');
- });
- document.getElementById('decrypt-link').addEventListener('click', (event) => {
- event.preventDefault();
- showSection('decrypt-section');
- });
- document.getElementById('about-link').addEventListener('click', (event) => {
- event.preventDefault();
- showSection('about-section');
- });
-
- // Initial display setup
- showSection('encrypt-section');
-
- document.getElementById('encrypt-button').addEventListener('click', handleEncrypt);
- document.getElementById('decrypt-button').addEventListener('click', handleDecrypt);
-});
-
-async function encryptImage(imageFile, message) {
- const base64Image = await fileToBase64(imageFile);
-
- const pythonCode = `
- from image_cipher import ImageCipher
- from PIL import Image
- from io import BytesIO
- import base64
- import json
-
- def encrypt_image(base64_image, message):
- image_data = base64.b64decode(base64_image.split(",")[1])
- image = Image.open(BytesIO(image_data))
- cipher = ImageCipher()
- encrypted_image = cipher.encode(image, message)
-
- buffer = BytesIO()
- encrypted_image.save(buffer, format="PNG")
- encoded_image_str = base64.b64encode(buffer.getvalue()).decode("utf-8")
- encoded_image_path = "data:image/png;base64," + encoded_image_str
-
- return json.dumps({"encoded_image_path": encoded_image_path})
-
- encrypt_image("${base64Image}", "${message}")
- `;
-
- const result = await pyodide.runPythonAsync(pythonCode);
- return result;
-}
-
-function fileToBase64(file) {
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onload = () => resolve(reader.result);
- reader.onerror = (error) => reject(error);
- reader.readAsDataURL(file);
- });
-}
-
-async function decryptImage(imageFilePath, key) {
- return pyodide.runPython(`
-from image_cipher import ImageCipher
-import json
-
-# Define a function to handle decryption
-def decrypt_image(image_file_path, key):
- cipher = ImageCipher()
- decoded_message = cipher.decode(image_file_path, key)
- return json.dumps({'decoded_message': decoded_message})
-
-# Call the function with passed arguments
-decrypt_image(image_file_path, key)
- `, { image_file_path: imageFilePath, key }); // Pass JavaScript variables here
-}
-
-
-async function handleEncrypt() {
- const imageFile = document.getElementById("encrypt-image").files[0];
- const message = document.getElementById("encrypt-message").value;
- console.log("image:", imageFile);
-
- if (imageFile && message) {
- // Create a URL for the file
- const imageUrl = URL.createObjectURL(imageFile);
- console.log("image URL:", imageUrl);
-
- // Display the image
- document.getElementById("encrypt-result").innerHTML = `Selected Image
`;
-
- // Encrypt the image
- const result = await encryptImage(imageFile, message);
- const data = JSON.parse(result);
- console.log(data);
-
- // Display the encrypted image
- document.getElementById("encrypt-result").innerHTML += `Encrypted Image
Download`;
- } else {
- alert("Please select an image and enter a message.");
- }
-}
-
-async function handleDecrypt() {
- const imageFile = document.getElementById("decrypt-image").files[0];
- const key = document.getElementById("decrypt-key").value;
-
- if (imageFile) {
- const reader = new FileReader();
- reader.onload = async function(event) {
- const imageFilePath = event.target.result;
- const result = await decryptImage(imageFilePath, key);
- const data = JSON.parse(result);
- document.getElementById("decrypt-result").innerHTML = `Decrypted Message
${data.decoded_message}
`;
- };
- reader.readAsDataURL(imageFile);
- } else {
- alert("Please select an image to decrypt.");
- }
-}
diff --git a/docs/server.py b/docs/server.py
deleted file mode 100644
index 7f69ff4..0000000
--- a/docs/server.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from flask import Flask, request, send_file, jsonify
-from image_cipher import ImageCipher
-from werkzeug.utils import secure_filename
-import os
-
-app = Flask(__name__)
-cipher = ImageCipher()
-
-UPLOAD_FOLDER = 'uploads'
-if not os.path.exists(UPLOAD_FOLDER):
- os.makedirs(UPLOAD_FOLDER)
-
-@app.route('/encode', methods=['POST'])
-def encode_image():
- if 'image' not in request.files or 'message' not in request.form:
- return jsonify({'error': 'No image or message provided'}), 400
-
- image = request.files['image']
- message = request.form['message']
- encrypt = request.form.get('encrypt', 'true').lower() == 'true'
-
- image_path = os.path.join(UPLOAD_FOLDER, secure_filename(image.filename))
- image.save(image_path)
-
- encoded_image_path = cipher.encode(image_path, message, encrypt)
- return send_file(encoded_image_path, as_attachment=True)
-
-@app.route('/decode', methods=['POST'])
-def decode_image():
- if 'image' not in request.files:
- return jsonify({'error': 'No image provided'}), 400
-
- image = request.files['image']
- key = request.form.get('key', None)
-
- image_path = os.path.join(UPLOAD_FOLDER, secure_filename(image.filename))
- image.save(image_path)
-
- message = cipher.decode(image_path, key)
- return jsonify({'message': message})
-
-if __name__ == '__main__':
- app.run(debug=True)
diff --git a/requirements.txt b/requirements.txt
index 9434775..18771f6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
Pillow==10.4.0
cryptography==42.0.8
pytest==8.2.2
-flake8==7.1.0
\ No newline at end of file
+flake8==7.1.0
+streamlit
\ No newline at end of file