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): print("encoding: ", 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 print("decoded:", decode(base_img.copy())) 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