RYU-KASH commited on
Commit
319dbb7
·
verified ·
1 Parent(s): 49a665a

Upload 5 files

Browse files
Files changed (5) hide show
  1. app.py +27 -0
  2. detection.py +75 -0
  3. picchange.py +163 -0
  4. stegnography.py +104 -0
  5. watermark.py +112 -0
app.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from picchange import img_cryptography
3
+ from stegnography import steganography_function
4
+ from detection import steganography_detection
5
+
6
+ # Sidebar Title
7
+ st.sidebar.title("IMAGENIAS")
8
+ st.sidebar.write("Choose a feature to proceed:")
9
+
10
+ # Add buttons in rows within the sidebar
11
+ crypto_button = st.sidebar.button("Crypto")
12
+ stego_button = st.sidebar.button("Steganography")
13
+ detect_button = st.sidebar.button("Detection")
14
+
15
+ # Main App Title
16
+ st.title("IMAGNIAS: Image Processing Toolkit")
17
+
18
+ # Trigger the corresponding function based on the clicked button
19
+ if crypto_button:
20
+ st.write("### Crypto Functionality")
21
+ img_cryptography()
22
+ elif stego_button:
23
+ st.write("### Steganography Functionality")
24
+ steganography_function()
25
+ else:
26
+ steganography_detection()
27
+
detection.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import numpy as np
4
+
5
+ def steganography_detection():
6
+ def lsb_analysis(image):
7
+ """
8
+ Analyzes the Least Significant Bits (LSB) of the image pixels
9
+ and checks for irregularities that might indicate hidden data.
10
+ """
11
+ img = Image.open(image)
12
+ img = img.convert('RGB') # Ensure RGB mode
13
+ pixels = np.array(img) # Convert image to numpy array
14
+
15
+ if len(pixels.shape) != 3 or pixels.shape[2] != 3:
16
+ raise ValueError("Unsupported image format. Please use RGB images.")
17
+
18
+ height, width, _ = pixels.shape
19
+
20
+ lsb_count = [0, 0] # Count of 0s and 1s in the LSB
21
+ lsb_distribution = []
22
+
23
+ # Loop through each pixel and channel
24
+ for y in range(height):
25
+ for x in range(width):
26
+ pixel = pixels[y, x]
27
+ for channel in range(3): # Process R, G, B channels
28
+ lsb = pixel[channel] & 1
29
+ lsb_count[lsb] += 1
30
+ lsb_distribution.append(lsb)
31
+
32
+ total_lsb = sum(lsb_count)
33
+ if total_lsb == 0:
34
+ return None, None
35
+
36
+ # Compute percentage distribution
37
+ lsb_percentage = [count / total_lsb * 100 for count in lsb_count]
38
+ return lsb_percentage, lsb_distribution
39
+
40
+ st.title("Steganography Detection Tool")
41
+ st.subheader("Analyze images for hidden messages based on LSB irregularities")
42
+
43
+ uploaded_image = st.file_uploader("Upload an image to analyze", type=["png", "jpg", "jpeg"])
44
+ analyze_button = st.button("Analyze Image")
45
+
46
+ if analyze_button:
47
+ if uploaded_image:
48
+ try:
49
+ st.image(uploaded_image, caption="Uploaded Image", use_column_width=True)
50
+ lsb_percentage, lsb_distribution = lsb_analysis(uploaded_image)
51
+
52
+ if lsb_percentage is None:
53
+ st.error("Unable to analyze the image.")
54
+ else:
55
+ st.write("### LSB Distribution Analysis")
56
+ st.write(f"**Percentage of LSBs:**\n- 0s: {lsb_percentage[0]:.2f}%\n- 1s: {lsb_percentage[1]:.2f}%")
57
+
58
+ # Visualization
59
+ st.write("### Visualization of LSB Distribution")
60
+ st.bar_chart({
61
+ "LSB Values": ["0s", "1s"],
62
+ "Percentage": lsb_percentage
63
+ })
64
+
65
+ # Detection threshold
66
+ threshold = 50 # Typically, natural images have an approximately equal distribution of 0s and 1s
67
+ if abs(lsb_percentage[0] - lsb_percentage[1]) > 5:
68
+ st.warning("The image shows irregular LSB distribution, suggesting possible steganographic modification.")
69
+ else:
70
+ st.success("The LSB distribution appears normal, with no clear indication of hidden data.")
71
+
72
+ except Exception as e:
73
+ st.error(f"An error occurred while analyzing the image: {e}")
74
+ else:
75
+ st.error("Please upload an image for analysis.")
picchange.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import numpy as np
4
+ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
5
+ from cryptography.hazmat.backends import default_backend
6
+ from cryptography.hazmat.primitives import padding
7
+ from io import BytesIO
8
+ def img_cryptography():
9
+
10
+ # Function to add padding to the image bytes
11
+ def pad_data(data):
12
+ try:
13
+ padder = padding.PKCS7(128).padder() # AES block size is 128 bits (16 bytes)
14
+ padded_data = padder.update(data) + padder.finalize()
15
+ return padded_data
16
+ except Exception as e:
17
+ raise ValueError(f"Padding Error: {e}")
18
+
19
+ # Function to remove padding after decryption
20
+ def unpad_data(data):
21
+ try:
22
+ unpadder = padding.PKCS7(128).unpadder()
23
+ unpadded_data = unpadder.update(data) + unpadder.finalize()
24
+ return unpadded_data
25
+ except Exception as e:
26
+ raise ValueError(f"Unpadding Error: {e}")
27
+
28
+ # Function to encrypt image using AES with a user-provided key
29
+ def encrypt_image(image_bytes, key):
30
+ try:
31
+ cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
32
+ encryptor = cipher.encryptor()
33
+
34
+ # Pad the image bytes before encryption
35
+ padded_bytes = pad_data(image_bytes)
36
+ encrypted_bytes = encryptor.update(padded_bytes) + encryptor.finalize()
37
+ return encrypted_bytes
38
+ except Exception as e:
39
+ raise ValueError(f"Encryption Error: {e}")
40
+
41
+ # Function to decrypt image using AES with a user-provided key
42
+ def decrypt_image(encrypted_bytes, key):
43
+ try:
44
+ cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend())
45
+ decryptor = cipher.decryptor()
46
+ decrypted_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize()
47
+
48
+ # Remove padding after decryption
49
+ unpadded_bytes = unpad_data(decrypted_bytes)
50
+ return unpadded_bytes
51
+ except ValueError as e:
52
+ raise ValueError(f"Decryption Error: Invalid padding or incorrect key - {e}")
53
+ except Exception as e:
54
+ raise ValueError(f"Decryption Error: {e}")
55
+
56
+ # Streamlit user interface
57
+ st.title("Image Encryption and Decryption using AES")
58
+
59
+ # Option for selecting key length
60
+ key_length = st.selectbox("Choose AES key length:", [16, 24, 32])
61
+
62
+ # Function to generate the AES key based on user input
63
+ def generate_key(key_input, length):
64
+ try:
65
+ key = key_input.encode('utf-8')
66
+ if len(key) < length:
67
+ # Pad the key with null bytes if it's shorter than the selected length
68
+ key = key.ljust(length, b'\0')
69
+ elif len(key) > length:
70
+ # Truncate the key if it's longer than the selected length
71
+ key = key[:length]
72
+ return key
73
+ except Exception as e:
74
+ raise ValueError(f"Key Generation Error: {e}")
75
+
76
+ # Input for AES Key
77
+ key_input = st.text_input(f"Enter AES encryption key (up to {key_length} characters):", type="password")
78
+
79
+ # Ensure the key is of the correct length after processing
80
+ if key_input and key_length:
81
+ key = generate_key(key_input, key_length)
82
+ else:
83
+ st.warning(f"Please enter a key of length {key_length} characters for encryption and decryption.")
84
+ key = None
85
+
86
+ # Create two columns for encryption and decryption sections
87
+ col1, col2 = st.tabs(["Encryption","Decryption"])
88
+
89
+ # ENCRYPTION SECTION (Left Column)
90
+ with col1:
91
+ st.header("Encryption")
92
+
93
+ # Option to upload image for encryption
94
+ uploaded_file = st.file_uploader("Choose an image to encrypt...", type=["jpg", "jpeg", "png"])
95
+
96
+ if uploaded_file is not None and key:
97
+ # Display the original image
98
+ image = Image.open(uploaded_file)
99
+ st.image(image, caption="Original Image", use_column_width=True)
100
+
101
+ if st.button("Encrypt"):
102
+ # Convert image to bytes for encryption
103
+ image_bytes = BytesIO()
104
+ image.save(image_bytes, format="PNG")
105
+ image_bytes = image_bytes.getvalue()
106
+
107
+ # Encrypt the image bytes
108
+ encrypted_bytes = encrypt_image(image_bytes, key)
109
+
110
+ # Save the encrypted bytes as a .bin file
111
+ encrypted_bin_file = "encrypted_image.bin"
112
+ with open(encrypted_bin_file, "wb") as f:
113
+ f.write(encrypted_bytes)
114
+
115
+ # To visualize encrypted data, truncate or pad it to match the original size
116
+ # Use numpy to create a grayscale view of the encrypted data
117
+ encrypted_array = np.frombuffer(encrypted_bytes, dtype=np.uint8)
118
+ padded_array = np.zeros(image.size[0] * image.size[1], dtype=np.uint8)
119
+ padded_array[:len(encrypted_array)] = encrypted_array[:len(padded_array)]
120
+
121
+ # Reshape to match image dimensions and visualize as a grayscale image
122
+ encrypted_image_array = padded_array.reshape(image.size[1], image.size[0])
123
+ encrypted_image = Image.fromarray(encrypted_image_array, mode="L")
124
+ encrypted_image_file = "encrypted_image.png"
125
+ encrypted_image.save(encrypted_image_file, format="PNG")
126
+
127
+ # Success message and download buttons
128
+ st.success("Image Encrypted Successfully!")
129
+ st.download_button(label="Download Encrypted BIN File", data=encrypted_bytes, file_name="encrypted_image.bin")
130
+ st.download_button(label="Download Encrypted PNG File", data=open(encrypted_image_file, "rb").read(), file_name="encrypted_image.png")
131
+ st.image(encrypted_image, caption="Encrypted Image (PNG)", use_column_width=True)
132
+
133
+
134
+ # DECRYPTION SECTION (Right Column)
135
+ with col2:
136
+ st.header("Decryption")
137
+
138
+ # Option to upload encrypted file for decryption (.bin only)
139
+ encrypted_file = st.file_uploader("Upload an encrypted file to decrypt (.bin only)...", type=["bin"])
140
+
141
+ if encrypted_file is not None and key:
142
+ try:
143
+ # Read encrypted binary data
144
+ encrypted_bytes = encrypted_file.read()
145
+
146
+ # Decrypt the image
147
+ decrypted_bytes = decrypt_image(encrypted_bytes, key)
148
+
149
+ # Convert decrypted bytes back to image
150
+ decrypted_image = Image.open(BytesIO(decrypted_bytes))
151
+ st.image(decrypted_image, caption="Decrypted Image", use_column_width=True)
152
+
153
+ # Save decrypted image as JPG
154
+ decrypted_image_file = "decrypted_image.jpg"
155
+ decrypted_image.save(decrypted_image_file, format="JPEG")
156
+
157
+ st.success("Image Decrypted Successfully!")
158
+ st.download_button(label="Download Decrypted Image (JPG)", data=open(decrypted_image_file, "rb").read(), file_name="decrypted_image.jpg")
159
+
160
+ except ValueError as e:
161
+ st.error(f"Error in decryption: {e}. This may indicate mismatched padding or incorrect decryption keys.")
162
+ except Exception as e:
163
+ st.error(f"Unexpected error: {e}")
stegnography.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import io
4
+ def steganography_function():
5
+ # Steganography functions
6
+ def encode_image(input_image, secret_message):
7
+ """Encodes a secret message into an image."""
8
+ img = Image.open(input_image)
9
+ encoded = img.copy()
10
+ width, height = img.size
11
+ pixels = encoded.load()
12
+
13
+ # Convert the message into binary and add a delimiter
14
+ binary_message = ''.join(format(ord(char), '08b') for char in secret_message) + '1111111111111110'
15
+ data_index = 0
16
+
17
+ for y in range(height):
18
+ for x in range(width):
19
+ if data_index < len(binary_message):
20
+ pixel = list(pixels[x, y])
21
+ # Modify the LSB of each RGB value
22
+ for i in range(3): # Process R, G, B channels
23
+ if data_index < len(binary_message):
24
+ pixel[i] = (pixel[i] & ~1) | int(binary_message[data_index])
25
+ data_index += 1
26
+ pixels[x, y] = tuple(pixel)
27
+
28
+ output = io.BytesIO()
29
+ encoded.save(output, format='PNG')
30
+ output.seek(0)
31
+ return output
32
+
33
+ def decode_image(encoded_image):
34
+ """Decodes a secret message from an image."""
35
+ img = Image.open(encoded_image)
36
+ width, height = img.size
37
+ pixels = img.load()
38
+
39
+ binary_message = ""
40
+ for y in range(height):
41
+ for x in range(width):
42
+ pixel = pixels[x, y]
43
+ for i in range(3): # Process R, G, B channels
44
+ binary_message += str(pixel[i] & 1)
45
+
46
+ # Split binary string into 8-bit chunks
47
+ message = ""
48
+ for i in range(0, len(binary_message), 8):
49
+ byte = binary_message[i:i+8]
50
+ if byte == '11111110': # Stop at the delimiter
51
+ break
52
+ message += chr(int(byte, 2))
53
+
54
+ return message
55
+
56
+ # Streamlit App
57
+ st.title("Steganography Tool")
58
+ st.subheader("Hide and retrieve secret messages in images")
59
+
60
+ # Tabs for Encode and Decode
61
+ tab1, tab2 = st.tabs(["🔒 Encode Message", "🔓 Decode Message"])
62
+
63
+ with tab1:
64
+ st.header("Encode a Secret Message")
65
+ uploaded_image = st.file_uploader("Upload an image to encode", type=["png", "jpg", "jpeg"])
66
+ if uploaded_image:
67
+ st.image(uploaded_image, caption="Selected Image for Encoding", use_column_width=True)
68
+ secret_message = st.text_area("Enter the secret message to hide")
69
+ encode_button = st.button("Apply Encoding")
70
+
71
+ if encode_button:
72
+ if uploaded_image and secret_message:
73
+ try:
74
+ encoded_image = encode_image(uploaded_image, secret_message)
75
+ st.success("Message encoded successfully!")
76
+ st.image(encoded_image, caption="Encoded Image", use_column_width=True)
77
+ st.download_button(
78
+ label="Download Encoded Image",
79
+ data=encoded_image,
80
+ file_name="encoded_image.png",
81
+ mime="image/png"
82
+ )
83
+ except Exception as e:
84
+ st.error(f"An error occurred: {e}")
85
+ else:
86
+ st.error("Please upload an image and enter a secret message.")
87
+
88
+ with tab2:
89
+ st.header("Decode a Secret Message")
90
+ encoded_image = st.file_uploader("Upload an image to decode", type=["png", "jpg", "jpeg"], key="decode")
91
+ if encoded_image:
92
+ st.image(encoded_image, caption="Selected Image for Decoding", use_column_width=True)
93
+ decode_button = st.button("Apply Decoding")
94
+
95
+ if decode_button:
96
+ if encoded_image:
97
+ try:
98
+ decoded_message = decode_image(encoded_image)
99
+ st.success("Message decoded successfully!")
100
+ st.text_area("Decoded Message", decoded_message, height=100)
101
+ except Exception as e:
102
+ st.error(f"An error occurred: {e}")
103
+ else:
104
+ st.error("Please upload an image to decode.")
watermark.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image, ImageDraw, ImageFont
3
+ import io
4
+ import numpy as np
5
+ def watermark_():
6
+ # Function to create a visible watermark on an image
7
+ def add_visible_watermark(image, watermark_text, size, opacity):
8
+ width, height = image.size
9
+ font_size = int(size)
10
+ try:
11
+ font = ImageFont.truetype("arial.ttf", font_size)
12
+ except IOError:
13
+ font = ImageFont.load_default()
14
+
15
+ # Create watermark layer
16
+ # Create watermark layer
17
+ watermark_layer = Image.new("RGBA", image.size, (255, 255, 255, 0))
18
+ watermark_draw = ImageDraw.Draw(watermark_layer)
19
+
20
+ # Calculate center position
21
+ text_width, text_height = watermark_draw.textbbox((0, 0), watermark_text, font=font)[2:]
22
+ x = (width - text_width) / 2
23
+ y = (height - text_height) / 2
24
+
25
+ # Add shadow
26
+ shadow_color = (0, 0, 0, int(opacity * 0.3))
27
+ watermark_draw.text((x + 3, y + 3), watermark_text, font=font, fill=shadow_color)
28
+
29
+ # Add main watermark in a slant line
30
+ watermark_color = (255, 255, 255, int(opacity))
31
+ for i in range(-width, width, text_width + 20):
32
+ watermark_draw.text((x + i, y + i), watermark_text, font=font, fill=watermark_color)
33
+
34
+
35
+ # Combine the watermark layer with the original image
36
+ combined_image = Image.alpha_composite(image.convert("RGBA"), watermark_layer).convert("RGB")
37
+ return combined_image
38
+
39
+ # Function to embed an invisible watermark in an image
40
+ def add_invisible_watermark(image, watermark_text):
41
+ binary_watermark = ''.join(format(ord(char), '08b') for char in watermark_text)
42
+ img_array = np.array(image)
43
+ flat_image = img_array.flatten()
44
+
45
+ for i in range(len(binary_watermark)):
46
+ flat_image[i] = flat_image[i] & ~1 | int(binary_watermark[i])
47
+
48
+ watermarked_image = flat_image.reshape(img_array.shape)
49
+ return Image.fromarray(watermarked_image.astype(np.uint8))
50
+
51
+ # Function to detect an invisible watermark in an image
52
+ def detect_invisible_watermark(image, watermark_length):
53
+ img_array = np.array(image)
54
+ flat_image = img_array.flatten()
55
+ binary_watermark = ''.join(str(flat_image[i] & 1) for i in range(watermark_length * 8))
56
+ watermark = ''.join(chr(int(binary_watermark[i:i + 8], 2)) for i in range(0, len(binary_watermark), 8))
57
+ return watermark
58
+
59
+ # Streamlit UI
60
+ def main():
61
+ st.title("Visible and Invisible Watermarking Tool")
62
+
63
+ col1, col2 = st.tabs(["Visible","Invisible"])
64
+
65
+ with col1:
66
+ st.header("Visible Watermark")
67
+ watermark_text = st.text_input("Enter Watermark Text", key="visible_text")
68
+
69
+ uploaded_file = st.file_uploader("Upload an Image", type=["png", "jpg", "jpeg"], key="visible_upload")
70
+
71
+ if uploaded_file and (watermark_text):
72
+ image = Image.open(uploaded_file).convert("RGB")
73
+
74
+ size = st.slider("Select Font Size", 10, 200, 50, key="font_size")
75
+ opacity = st.slider("Select Opacity", 0, 255, 128, key="opacity")
76
+
77
+
78
+ watermarked_image = add_visible_watermark(
79
+ image, watermark_text, size, opacity
80
+ )
81
+
82
+ st.image(watermarked_image, caption="Watermarked Image")
83
+ buffer = io.BytesIO()
84
+ watermarked_image.save(buffer, format="PNG")
85
+ st.download_button("Download Watermarked Image", buffer.getvalue(), "visible_watermarked_image.png")
86
+
87
+ with col2:
88
+ st.header("Invisible Watermark")
89
+
90
+ watermark_text = st.text_input("Enter Invisible Watermark Text", key="invisible_text")
91
+ uploaded_file = st.file_uploader("Upload an Image", type=["png", "jpg", "jpeg"], key="invisible_upload")
92
+
93
+ if uploaded_file and watermark_text:
94
+ image = Image.open(uploaded_file).convert("RGB")
95
+ watermarked_image = add_invisible_watermark(image, watermark_text)
96
+
97
+ st.image(watermarked_image, caption="Image with Invisible Watermark")
98
+ buffer = io.BytesIO()
99
+ watermarked_image.save(buffer, format="PNG")
100
+ st.download_button("Download Image with Invisible Watermark", buffer.getvalue(), "invisible_watermarked_image.png")
101
+
102
+ if st.checkbox("Check Invisible Watermark"):
103
+ uploaded_file = st.file_uploader("Upload an Image to Check Watermark", type=["png", "jpg", "jpeg"], key="check_upload")
104
+ watermark_length = st.number_input("Enter Watermark Length", min_value=1, step=1, key="watermark_length")
105
+
106
+ if uploaded_file and watermark_length:
107
+ image = Image.open(uploaded_file).convert("RGB")
108
+ extracted_watermark = detect_invisible_watermark(image, watermark_length)
109
+ st.write("Extracted Watermark:", extracted_watermark)
110
+
111
+ if __name__ == "__main__":
112
+ main()