Bruno Tripoloni
Bruno Tripoloni

Reputation: 43

mixing pixels of an image manually using python

I am trying to create an algorithm that blends the pixels of an image and I can bring the image as it was before, but I do not know do this.

I'm using python and pil, but I can use other libraries.

Exemple: enter image description here to enter image description here and back to enter image description here

Thank you.

Upvotes: 0

Views: 3189

Answers (1)

drhodes
drhodes

Reputation: 1009

This should do it. There's no error handling, it doesn't follow pep8 standards, it uses slow PIL operations and it doesn't use an argument parsing library. I'm sure there are other bad things about it also.

It works by seeding python's random number generator with an invariant of the image under scrambling. The hash of the size is used. Since the size doesn't changed, a random sequence built on it will be the same for all images that share the same size. That sequence is used as a one-to-one mapping, therefore it's reversible.

The script may be invoked twice from a shell to create two images, "scrambled.png" and "unscrambled.png". "Qfhe3.png" is the source image.

python scramble.py scramble "./Qfhe3.png"
python scramble.py unscramble "./scrambled.png"
#scramble.py
from PIL import Image
import sys
import os
import random

def openImage():
    return Image.open(sys.argv[2])

def operation():
    return sys.argv[1]

def seed(img):
    random.seed(hash(img.size))

def getPixels(img):
    w, h = img.size
    pxs = []
    for x in range(w):
        for y in range(h):
            pxs.append(img.getpixel((x, y)))
    return pxs

def scrambledIndex(pxs):
    idx = list(range(len(pxs)))
    random.shuffle(idx)
    return idx

def scramblePixels(img):
    seed(img)
    pxs = getPixels(img)
    idx = scrambledIndex(pxs)
    out = []
    for i in idx:
        out.append(pxs[i])
    return out

def unScramblePixels(img):
    seed(img)
    pxs = getPixels(img)
    idx = scrambledIndex(pxs)
    out = list(range(len(pxs)))
    cur = 0
    for i in idx:
        out[i] = pxs[cur]
        cur += 1
    return out

def storePixels(name, size, pxs):
    outImg = Image.new("RGB", size)
    w, h = size
    pxIter = iter(pxs)
    for x in range(w):
        for y in range(h):
            outImg.putpixel((x, y), next(pxIter))
    outImg.save(name)

def main():
    img = openImage()
    if operation() == "scramble":
        pxs = scramblePixels(img)
        storePixels("scrambled.png", img.size, pxs)
    elif operation() == "unscramble":
        pxs = unScramblePixels(img)
        storePixels("unscrambled.png", img.size, pxs)
    else:
        sys.exit("Unsupported operation: " + operation())

if __name__ == "__main__":
    main()

Upvotes: 5

Related Questions