Skip to content

Instantly share code, notes, and snippets.

@jdonszelmann
Created April 14, 2019 19:16
Show Gist options
  • Save jdonszelmann/1d71c671d8780469bfed92e69bbc4085 to your computer and use it in GitHub Desktop.
Save jdonszelmann/1d71c671d8780469bfed92e69bbc4085 to your computer and use it in GitHub Desktop.
from PIL import Image, ImageDraw, ImageChops
import os
path = os.path.dirname(os.path.abspath(__file__))
size = (480,360)
class LCG:
def __init__(self,m,a,c,seed):
self.m = m
self.a = a
self.c = c
self.seed = seed
def next(self):
while True:
self.seed = (self.a * self.seed + self.c) % self.m
return self.seed
def delfolder(folder):
for i in os.listdir(os.path.join(path,folder)):
os.remove(os.path.join(path,folder,i))
def random_image(lcg):
im = Image.new("L",size)
pix = im.load()
print(lcg.seed)
for i in range(0,im.size[1],2): # for every pixel interlaced even:
for j in range(im.size[0]):
dat = lcg.next()
pix[j,i] = dat % 255
for i in range(1,im.size[1],2): # for every pixel interlaced odd:
for j in range(im.size[0]):
dat = lcg.next()
pix[j,i] = dat % 255
return im
def open_image(path):
return Image.open(path).resize(size,Image.ANTIALIAS)
def readframes(dir):
frames = []
for i in sorted(os.listdir(os.path.join(path,dir)),key=lambda i: int(i.replace("image","").replace(".png",""))):
frames.append(
open_image(os.path.join(path,dir,i))
)
return frames
def extractFrames(gif, folder):
with Image.open(gif) as im:
print(">",im.n_frames)
for i in range(im.n_frames):
im.seek(i)
im.save('{}/image{}.png'.format(os.path.join(path,folder), str(i)), "PNG")
def xor(im,other):
assert im.size == other.size
res = Image.new("L",im.size)
pix = res.load()
pix1 = im.load()
pix2 = other.load()
for i in range(im.size[0]): # for every pixel:
for j in range(im.size[1]):
pix[i,j] = pix1[i,j] ^ pix2[i,j]
return res
# 50000
def encode(intro, data, out, generator):
frames = []
introframe = open_image(intro).convert('L').resize(size)
for i in range(10):
frames.append(introframe)
delfolder("images")
extractFrames(data,"images")
dataframes = readframes("images")
introframe.load()
for index,i in enumerate(dataframes):
encodingframe = random_image(generator)
print("combining image {}/{}".format(index+1,len(dataframes)))
newimg = i.resize(size, Image.ANTIALIAS).convert('L')
newimg.load()
frames.append(xor(newimg,encodingframe))
newframes = []
for index,i in enumerate(frames):
print("converting image {}/{}".format(index+1,len(frames)))
newframes.append(i.convert("RGB"))
frames = newframes
print(len(frames))
# Save into a GIF file that loops forever
frames[0].save(out, format='GIF', append_images=frames[1:], save_all=True, duration=100, loop=0)
# ffmpeg -i data.gif -c:v gif images/out%04d.png
def decode(inp,out, generator, ignore=1):
delfolder("images")
extractFrames(inp,"images")
dataframes = readframes("images")
frames = []
for index,i in enumerate(dataframes[ignore:]):
decodingframe = random_image(generator)
print("restoring frame {}/{}".format(index+1,len(dataframes)))
newimg = i.convert('L')
newimg.load()
frames.append(xor(newimg,decodingframe))
newframes = []
for index,i in enumerate(frames):
print("converting image {}/{}".format(index+1,len(frames)))
newframes.append(i.convert("RGB"))
frames = newframes
print(len(frames))
frames[0].save(out, format='GIF', append_images=frames[1:], save_all=True, duration=100, loop=0)
if __name__ == "__main__":
encode(
os.path.join(path,"introframe.png"),
os.path.join(path,"data4.gif"),
os.path.join(path,"result.gif"),
LCG((2**61)-1,13,7,424242)
)
decode(
os.path.join(path,"result.gif"),
os.path.join(path,"decodedresult.gif"),
LCG((2**61)-1,13,7,424242),
1
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment