-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgifsteg.py
156 lines (122 loc) · 4.64 KB
/
gifsteg.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
152
153
154
155
156
from PIL import Image,ImageSequence, GifImagePlugin
import os
def to_bin(data):
if isinstance(data, str):
return ''.join([format(ord(i), "08b") for i in data])
elif isinstance(data, bytes) or isinstance(data, bytearray):
return [format(i, "08b") for i in data]
elif isinstance(data, int) or isinstance(data, np.uint8):
return format(data, "08b")
else:
raise TypeError("Type is not supported")
def encode_image(image_path, secret_data, number_of_bits):
gif = Image.open(image_path)
frames = []
for frame in ImageSequence.Iterator(gif):
image = frame.convert("RGB")
frames.append(image.copy())
max_bytes = frames[0].size[0] * frames[0].size[1] * 3 // 8
print("Maximum bytes to encode: ", max_bytes)
secret_data += "#####"
if len(secret_data) > max_bytes:
raise ValueError("Insufficient bits")
print("Encoding image")
data_index = 0
bin_secret_data = to_bin(secret_data)
data_len = len(bin_secret_data)
counter = 128
count = 0
encode_text = open('encode.txt', 'w')
for frame in frames:
pixels = frame.load()
for y in range(frame.size[1]):
for x in range(frame.size[0]):
r, g, b = pixels[x, y]
r, g, b = to_bin(r), to_bin(g), to_bin(b)
info = ""
for i in range(number_of_bits):
if data_index < data_len:
info += bin_secret_data[data_index]
data_index += 1
else:
info += "0"
r = int(r[:-number_of_bits] + info, 2)
info = ""
for i in range(number_of_bits):
if data_index < data_len:
info += bin_secret_data[data_index]
data_index += 1
else:
info += "0"
g = int(g[:-number_of_bits] + info, 2)
info = ""
for i in range(number_of_bits):
if data_index < data_len:
info += bin_secret_data[data_index]
data_index += 1
else:
info += "0"
b = int(b[:-number_of_bits] + info, 2)
pixels[x, y] = (r, g, b)
if count < counter:
encode_text.write(str((r, g, b)))
encode_text.write('\n')
count += 1
if data_index >= data_len:
break
if data_index >= data_len:
break
if data_index >= data_len:
break
encode_text.close()
file_name, file_extension = os.path.splitext(image_path)
#output_path = file_name + "_encoded" + file_extension
output_path = "encoded_gif.gif"
frames[0].save(output_path, save_all=True, append_images=frames[1:], loop=0, duration=gif.info['duration'])
print(len(frames))
print("Image successfully encoded: " + output_path)
return output_path
def decode_image(image_path, number_of_bits):
print("Decoding image")
image = Image.open(image_path)
frames = []
for frame in ImageSequence.Iterator(image):
frames.append(frame.convert("RGBA"))
bin_data = ""
counter = 128
count = 0
decode_text = open('decode.txt', 'w')
for frame in frames:
pixels = frame.load()
for y in range(frame.size[1]):
for x in range(frame.size[0]):
if count < counter:
decode_text.write(str(pixels[x, y]))
decode_text.write('\n')
count += 1
r, g, b, a = pixels[x, y]
r, g, b = to_bin(r), to_bin(g), to_bin(b)
bin_data += r[-number_of_bits:]
bin_data += g[-number_of_bits:]
bin_data += b[-number_of_bits:]
decode_text.close()
all_bytes = [bin_data[i: i + 8] for i in range(0, len(bin_data), 8)]
decoded_data = ""
for byte in all_bytes:
decoded_data += chr(int(byte, 2))
if decoded_data[-5:] == "#####":
break
print("Image successfully decoded")
return decoded_data[:-5]
"""
# Example usage
image_path = 'bears.gif'
output_path = 'bears_encoded.gif'
message = "This is a secret message!"
number_of_bits = 1
# Hide the message in the GIF image
encode_image(image_path, message, number_of_bits)
# Reveal the message from the encoded GIF image
revealed_message = decode_image(output_path, number_of_bits)
print("Revealed message:", revealed_message)
"""