-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
executable file
·153 lines (111 loc) · 4.26 KB
/
main.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#import libraries
from PIL import Image
def int_to_bin(rgb):
"""Convert an integer tuple to a binary (string) tuple.
:param rgb: An integer tuple (e.g. (220, 110, 96))
:return: A string tuple (e.g. ("00101010", "11101011", "00010110"))
"""
r, g, b = rgb
return ('{0:08b}'.format(r),
'{0:08b}'.format(g),
'{0:08b}'.format(b))
def bin_to_int(rgb):
"""Convert a binary (string) tuple to an integer tuple.
:param rgb: A string tuple (e.g. ("00101010", "11101011", "00010110"))
:return: Return an int tuple (e.g. (220, 110, 96))
"""
r, g, b = rgb
return (int(r, 2),
int(g, 2),
int(b, 2))
def merge_rgb(rgb1, rgb2):
"""Merge two RGB tuples.
:param rgb1: A string tuple (e.g. ("00101010", "11101011", "00010110"))
:param rgb2: Another string tuple
(e.g. ("00101010", "11101011", "00010110"))
:return: An integer tuple with the two RGB values merged.
"""
r1, g1, b1 = rgb1
r2, g2, b2 = rgb2
rgb = (r1[:4] + r2[:4],
g1[:4] + g2[:4],
b1[:4] + b2[:4])
return rgb
def merge(img1, img2):
"""Merge two images. The second one will be merged into the first one.
:param img1: First image
:param img2: Second image
:return: A new merged image.
"""
# Check the images dimensions
if img2.size[0] > img1.size[0] or img2.size[1] > img1.size[1]:
raise ValueError('Image 2 should not be larger than Image 1!')
# 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 = int_to_bin(pixel_map1[i, j])
# Use a black pixel as default
rgb2 = 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 = int_to_bin(pixel_map2[i, j])
# Merge the two pixels and convert it to a integer tuple
rgb = merge_rgb(rgb1, rgb2)
pixels_new[i, j] = bin_to_int(rgb)
return new_image
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 = 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
rgb = (r[4:] + '0000',
g[4:] + '0000',
b[4:] + '0000')
# Convert it to an integer tuple
pixels_new[i, j] = 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 merger(img1, img2, output):
merged_image = merge(img1, img2)
merged_image.save(output)
def unmerger(img, output):
unmerged_image = unmerge(Image.open(img))
unmerged_image.save(output)
inp = int(input("Select option: \n\t0 --> Encrypt\n\t1 --> Decrypt\n"))
if(inp == 0):
img1_name = input("Image to be shown : ")
img2_name = input("Image to be hidden : ")
img_1 = Image.open(img1_name)
img_2 = Image.open(img2_name)
if(img_2.size<img_1.size):
merger(img_1,img_2,'output.png')
print("Encrypted successfully ! --> output.png")
else:
print("First image should be larger!")
elif(inp == 1):
img3 = input("Image to be decrypted : ")
unmerger(img3,'extracted.png')
print("Decrypted successfully ! --> extracted.png")