Spaces:
Sleeping
Sleeping
| from PIL import Image | |
| import numpy as np | |
| import streamlit as st | |
| import io | |
| import time | |
| import random | |
| # Resize image to prevent memory issues with large images | |
| def resize_image(img, max_size=(3000, 3000)): | |
| """ | |
| Resize image to fit within max_size while maintaining aspect ratio. | |
| """ | |
| img.thumbnail(max_size, Image.Resampling.LANCZOS) | |
| return img | |
| # Logistic map function | |
| def logistic_map(r, x): | |
| return r * x * (1 - x) | |
| # Generate chaotic key based on the logistic map | |
| def generate_key(seed, n): | |
| key = [] | |
| x = seed | |
| for _ in range(n): | |
| x = logistic_map(3.9, x) | |
| key.append(int(x * 255) % 256) # Map to 0-255 | |
| return np.array(key, dtype=np.uint8) | |
| # Shuffle pixels using a chaotic sequence | |
| def shuffle_pixels(img_array, seed): | |
| h, w, c = img_array.shape | |
| num_pixels = h * w | |
| flattened = img_array.reshape(-1, c) | |
| indices = np.arange(num_pixels) | |
| random.seed(seed) | |
| random.shuffle(indices) # Shuffle indices | |
| shuffled = flattened[indices] | |
| return shuffled.reshape(h, w, c), indices | |
| # Multi-layer encryption using logistic map and pixel shuffling | |
| def encrypt_image(img_array, seed): | |
| h, w, c = img_array.shape | |
| flat_image = img_array.flatten() | |
| # Generate chaotic key | |
| chaotic_key = generate_key(seed, len(flat_image)) | |
| # XOR-based encryption | |
| encrypted_flat = [pixel ^ chaotic_key[i] for i, pixel in enumerate(flat_image)] | |
| encrypted_array = np.array(encrypted_flat, dtype=np.uint8).reshape(h, w, c) | |
| # Pixel shuffling | |
| shuffled_array, indices = shuffle_pixels(encrypted_array, seed) | |
| # Second layer of logistic map encryption | |
| chaotic_key_2 = generate_key(seed * 1.1, len(flat_image)) | |
| shuffled_flat = shuffled_array.flatten() | |
| doubly_encrypted_flat = [pixel ^ chaotic_key_2[i] for i, pixel in enumerate(shuffled_flat)] | |
| doubly_encrypted_array = np.array(doubly_encrypted_flat, dtype=np.uint8).reshape(h, w, c) | |
| return doubly_encrypted_array | |
| # Decrypt function | |
| def decrypt_image(encrypted_array, seed, original_shape): | |
| h, w, c = original_shape | |
| flat_image = encrypted_array.flatten() | |
| # Generate the second chaotic key | |
| chaotic_key_2 = generate_key(seed * 1.1, len(flat_image)) | |
| # Reverse the second XOR encryption | |
| xor_reversed_flat = [pixel ^ chaotic_key_2[i] for i, pixel in enumerate(flat_image)] | |
| xor_reversed_array = np.array(xor_reversed_flat, dtype=np.uint8).reshape(h, w, c) | |
| # Reverse pixel shuffling | |
| shuffled_array = xor_reversed_array | |
| num_pixels = h * w | |
| flattened = shuffled_array.reshape(-1, c) | |
| indices = np.arange(num_pixels) | |
| random.seed(seed) | |
| random.shuffle(indices) # Reuse the same shuffle logic | |
| unshuffled = np.zeros_like(flattened) | |
| unshuffled[indices] = flattened | |
| unshuffled_array = unshuffled.reshape(h, w, c) | |
| # Generate the first chaotic key | |
| chaotic_key_1 = generate_key(seed, len(flat_image)) | |
| # Reverse the first XOR encryption | |
| decrypted_flat = [pixel ^ chaotic_key_1[i] for i, pixel in enumerate(unshuffled_array.flatten())] | |
| decrypted_array = np.array(decrypted_flat, dtype=np.uint8).reshape(h, w, c) | |
| return decrypted_array | |
| # Streamlit App | |
| def main(): | |
| st.title("Enhanced Chaotic Logistic Map Image Encryption") | |
| st.write("Upload an image to encrypt and decrypt using advanced chaotic logistic map methods.") | |
| uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"]) | |
| if uploaded_file is not None: | |
| with st.spinner("Processing upload..."): | |
| # Simulate a loading delay for upload progress | |
| progress_bar = st.progress(0) | |
| for percent_complete in range(0, 101, 20): | |
| time.sleep(0.1) # Simulate progress | |
| progress_bar.progress(percent_complete) | |
| # Load the uploaded image | |
| input_image = Image.open(uploaded_file) | |
| # Resize the image if necessary | |
| input_image = resize_image(input_image) | |
| # Display original image | |
| st.image(input_image, caption="Uploaded Image", use_container_width=True) | |
| # Convert image to numpy array | |
| img_array = np.array(input_image) | |
| # Key input | |
| key_seed = st.slider("Set the encryption key seed (0 < key < 1)", min_value=0.001, max_value=0.999, step=0.001) | |
| # Encrypt Image | |
| if st.button("Encrypt Image"): | |
| with st.spinner("Encrypting image..."): | |
| # Simulate a loading delay for encryption progress | |
| progress_bar = st.progress(0) | |
| for percent_complete in range(0, 101, 20): | |
| time.sleep(0.1) # Simulate progress | |
| progress_bar.progress(percent_complete) | |
| # Encrypt the image | |
| encrypted_array = encrypt_image(img_array, key_seed) | |
| encrypted_image = Image.fromarray(encrypted_array) | |
| # Store encrypted array in session state | |
| st.session_state["encrypted_array"] = encrypted_array | |
| st.session_state["original_shape"] = img_array.shape | |
| st.session_state["key_seed"] = key_seed | |
| # Display encrypted image | |
| st.image(encrypted_image, caption="Encrypted Image", use_container_width=True) | |
| # Save encrypted image to a buffer | |
| buffer = io.BytesIO() | |
| encrypted_image.save(buffer, format="PNG") | |
| buffer.seek(0) | |
| # Download button for encrypted image | |
| st.download_button( | |
| label="Download Encrypted Image", | |
| data=buffer, | |
| file_name="encrypted_image.png", | |
| mime="image/png" | |
| ) | |
| # Decrypt Image | |
| if st.button("Decrypt Image"): | |
| if "encrypted_array" in st.session_state: | |
| with st.spinner("Decrypting image..."): | |
| decrypted_array = decrypt_image( | |
| st.session_state["encrypted_array"], | |
| st.session_state["key_seed"], | |
| st.session_state["original_shape"] | |
| ) | |
| decrypted_image = Image.fromarray(decrypted_array) | |
| # Display decrypted image | |
| st.image(decrypted_image, caption="Decrypted Image", use_container_width=True) | |
| else: | |
| st.error("No encrypted image found. Please encrypt an image first.") | |
| if __name__ == "__main__": | |
| main() | |