I'm trying to hide messages within images by changing the least significant bit (LSB) then read those same bits to retrieve the hidden message.
When the image is not saved and the program just iterates through the array of RGB values, it works as expected but when I use:
res_img = Image.fromarray(im)
res_img.save("freshly_hidden_message.jpg")
The output array is mutated and it's fully unable to read the hidden message.
This is the part that's supposed to read the message:
while msg[-5:] != "^END^":
bits = [bin(i)[-1] for i in im[index:index + 8]]
print(bits)
bits = "".join(bits)
msg += chr(int(bits, 2))
index += 8
print("Hidden message is:",msg[:-5])
While this part hides the message within LSB's:
for index, bit in enumerate(hidden_message_bits):
val = im[index]
val = bin(val)
val = val[:-1] + bit
im[index] = int(val, 2)
Sample output without saving:
['0', '1', '0', '1', '0', '1', '0', '0']
['0', '1', '1', '0', '0', '1', '0', '1']
['0', '1', '1', '1', '0', '0', '1', '1']
['0', '1', '1', '1', '0', '1', '0', '0']
['0', '1', '1', '0', '1', '0', '0', '1']
['0', '1', '1', '0', '1', '1', '1', '0']
['0', '1', '1', '0', '0', '1', '1', '1']
['0', '1', '0', '1', '1', '1', '1', '0']
['0', '1', '0', '0', '0', '1', '0', '1']
['0', '1', '0', '0', '1', '1', '1', '0']
['0', '1', '0', '0', '0', '1', '0', '0']
['0', '1', '0', '1', '1', '1', '1', '0']
Hidden message is: Testing
Sample output with saving:
['1', '0', '0', '1', '0', '0', '1', '0']
['0', '0', '1', '1', '0', '1', '1', '1']
['0', '0', '1', '0', '0', '1', '0', '0']
['1', '0', '0', '1', '0', '0', '1', '0']
['0', '1', '0', '0', '1', '0', '0', '1']
['0', '0', '1', '0', '0', '1', '0', '0']
['0', '0', '1', '0', '0', '1', '0', '0']
['1', '0', '0', '1', '0', '0', '1', '0']
['0', '1', '0', '0', '1', '0', '0', '1']
['0', '0', '1', '0', '0', '1', '0', '0']
['1', '0', '0', '1', '0', '0', '1', '0']
['0', '1', '0', '0', '1', '0', '0', '1']
Hidden message is: 7$I$$I$I$I$I$I$I$I$IÛm¶Ûm¶$IÛm¶Ûm¶$Iÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$I$I$I$I$I$Iÿÿÿÿÿÿ