from PIL import Image # Chargement / Sauvegarde des images
import numpy as np    # Manipulations matricielles

def combine(i1, i2, n): 
    """ Cache les n bits de poids fort de i1 dans i2 """ 
    # On place les n bits de poids fort de i1 en position poids faible
    i3 = i1 >> (8 - n)
    # Annulation des n bits de poids faible de i2
    mask = 0xff - (2**n - 1)  
    i4 = i2 & mask
    return i4 + i3
            
def retrouve(i3, n): 
    """ Retrouve dans i3 une image cachée en utilisant 
        les n bits de poids faible """ 
    return (i3 << (8 - n)) & 0xff
                                                                                       
## Utilisation sur 2 images de même taille
i1 = np.asarray(Image.open("image1.png"))
i2 = np.asarray(Image.open("image2.png"))
assert i1.shape == i2.shape
i3 = combine(i1, i2, 3)
im3 = Image.fromarray(i3)
im3.save("image3.png")                                                                                                                                                               
im3.show()
i4 = retrouve(i3, 3)
im4 = Image.fromarray(i4)
im4.save("image4.png")
im4.show()

