-
Notifications
You must be signed in to change notification settings - Fork 0
/
steganography.py
132 lines (90 loc) · 3.87 KB
/
steganography.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import argparse
from PIL import Image
class Steganography(object):
@staticmethod
def __int_to_bin(rgb):
r, g, b = rgb
return ('{0:08b}'.format(r),
'{0:08b}'.format(g),
'{0:08b}'.format(b))
@staticmethod
def __bin_to_int(rgb):
r, g, b = rgb
return (int(r, 2),
int(g, 2),
int(b, 2))
@staticmethod
def __merge_rgb(rgb1, rgb2):
r1, g1, b1 = rgb1
r2, g2, b2 = rgb2
rgb = (r1[:4] + r2[:4],
g1[:4] + g2[:4],
b1[:4] + b2[:4])
return rgb
@staticmethod
def merge(img1, img2):
# Get the pixel map of the two images
pixel_map1 = img1.load()
pixel_map2 = img2.load()
# Create a new image that will be outputted
new_image = Image.new(img1.mode, img1.size)
pixels_new = new_image.load()
for i in range(img1.size[0]):
for j in range(img1.size[1]):
rgb1 = Steganography.__int_to_bin(pixel_map1[i, j])
# Use a black pixel as default
rgb2 = Steganography.__int_to_bin((0, 0, 0))
# Check if the pixel map position is valid for the second image
if i < img2.size[0] and j < img2.size[1]:
rgb2 = Steganography.__int_to_bin(pixel_map2[i, j])
# Merge the two pixels and convert it to a integer tuple
rgb = Steganography.__merge_rgb(rgb1, rgb2)
pixels_new[i, j] = Steganography.__bin_to_int(rgb)
return new_image
@staticmethod
def unmerge(img):
"""
Unmerge an image.
:param img: The input image.
:return: The unmerged/extracted image.
"""
# Load the pixel map
pixel_map = img.load()
# Create the new image and load the pixel map
new_image = Image.new(img.mode, img.size)
pixels_new = new_image.load()
# Tuple used to store the image original size
original_size = img.size
for i in range(img.size[0]):
for j in range(img.size[1]):
# Get the RGB (as a string tuple) from the current pixel
r, g, b = Steganography.__int_to_bin(pixel_map[i, j])
# Extract the last 4 bits (corresponding to the hidden image)
# Concatenate 4 zero bits because we are working with 8 bit values
rgb = (r[4:] + "0000",
g[4:] + "0000",
b[4:] + "0000")
# Convert it to an integer tuple
pixels_new[i, j] = Steganography.__bin_to_int(rgb)
# If this is a 'valid' position, store it
# as the last valid position
if pixels_new[i, j] != (0, 0, 0):
original_size = (i + 1, j + 1)
# Crop the image based on the 'valid' pixels
new_image = new_image.crop((0, 0, original_size[0], original_size[1]))
return new_image
def main():
# If the input_image2 argument is valid (not empty), the user
# is trying to merge two images, so call the merge method
num=input("Enter 1 for encrypt and 2 for decrpyt : ")
if(num==1): #merging of images
img1 = Image.open(open("/home/alok/Desktop/stgn/res/baby.png", 'rb'))
img2 = Image.open(open("/home/alok/Desktop/stgn/res/mom.png", 'rb'))
merged_image = Steganography.merge(img1, img2)
merged_image.save("/home/alok/Desktop/stgn/res/merge.png")
else: #unmerging of images
img = Image.open(open("/home/alok/Desktop/stgn/res/merge.png", 'rb'))
unmerged_image = Steganography.unmerge(img)
unmerged_image.save("/home/alok/Desktop/stgn/res/final.png")
if __name__ == "__main__":
main()