Spaces:
Sleeping
Sleeping
""" | |
Note, this heavily builds upon | |
https://gist.github.com/goelashwin36/6847a974c9b7b2ca500154d5c89d1d76 | |
""" | |
from email.mime import base | |
import glob | |
import random | |
from PIL import Image | |
def random_base_img(): | |
img_fn = random.choice(glob.glob("./base_images/*.jpg")) | |
return Image.open(img_fn, "r") | |
def modify_pixel(pixel, data): | |
data_lst = [format(ord(d), "08b") for d in data] | |
data_len = len(data_lst) | |
imdata = iter(pixel) | |
for i in range(data_len): | |
pix = [ | |
value | |
for value in imdata.__next__()[:3] | |
+ imdata.__next__()[:3] | |
+ imdata.__next__()[:3] | |
] | |
# Pixel value should be made | |
# odd for 1 and even for 0 | |
for j in range(0, 8): | |
if data_lst[i][j] == "0" and pix[j] % 2 != 0: | |
pix[j] -= 1 | |
elif data_lst[i][j] == "1" and pix[j] % 2 == 0: | |
if pix[j] != 0: | |
pix[j] -= 1 | |
else: | |
pix[j] += 1 | |
# Eighth pixel of every set tells | |
# whether to stop ot read further. | |
# 0 means keep reading; 1 means thec | |
# message is over. | |
if i == data_len - 1: | |
if pix[-1] % 2 == 0: | |
if pix[-1] != 0: | |
pix[-1] -= 1 | |
else: | |
pix[-1] += 1 | |
else: | |
if pix[-1] % 2 != 0: | |
pix[-1] -= 1 | |
pix = tuple(pix) | |
yield pix[0:3] | |
yield pix[3:6] | |
yield pix[6:9] | |
def encode(data): | |
base_img = random_base_img() | |
w = base_img.size[0] | |
(x, y) = (0, 0) | |
for pixel in modify_pixel(base_img.getdata(), data): | |
base_img.putpixel((x, y), pixel) | |
if x == w - 1: | |
x = 0 | |
y += 1 | |
else: | |
x += 1 | |
return base_img.copy() | |
def decode(img): | |
data = "" | |
imgdata = iter(img.getdata()) | |
while True: | |
pixels = [ | |
value | |
for value in imgdata.__next__()[:3] | |
+ imgdata.__next__()[:3] | |
+ imgdata.__next__()[:3] | |
] | |
# string of binary data | |
binstr = "" | |
for i in pixels[:8]: | |
if i % 2 == 0: | |
binstr += "0" | |
else: | |
binstr += "1" | |
data += chr(int(binstr, 2)) | |
if pixels[-1] % 2 != 0: | |
return data | |