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 | |