Image Fractalizor

Created a nifty python script that takes images and turns them into fractals (self-symmetric images with non-integer dimensions)

For the non-math-nerd, it takes an image like this:

http://nagolinc.googlepages.com/blob.png

and turns it into this:

http://nagolinc.googlepages.com/blobfrac.png

Or one like this:


And turns it into:

The only important limitation is that the images i[]MUST[/i] be 2^x by 2^x (eg. 256256 or 512512). If you use images that aren’t you’ll get an error

Also, this takes a lot of computation. The limit on my computer seems to be about 1056*1056.



import Blender
from Blender import Image

##Import the image##

img=Image.GetCurrent()

(x,y)=img.getSize()

print x,y


##initialize the color arrays##

raa=range(x)
for i in range(x):
    raa[i]=range(y)
for i in range(x):
    for j in range(y):
        p=img.getPixelF(i,j)
        raa[i][j]=p[0]

gaa=range(x)
for i in range(x):
    gaa[i]=range(y)
for i in range(x):
    for j in range(y):
        p=img.getPixelF(i,j)
        gaa[i][j]=p[1]
        
baa=range(x)
for i in range(x):
    baa[i]=range(y)
for i in range(x):
    for j in range(y):
        p=img.getPixelF(i,j)
        baa[i][j]=p[2]
                

##fractalize each of the color arrayz##

n=0

while 2**n<=x:
    
    rbb=range(x)
    for i in range(x):
        rbb[i]=range(y)
    gbb=range(x)
    for i in range(x):
        gbb[i]=range(y)
    bbb=range(x)
    for i in range(x):
        bbb[i]=range(y)


    for i in range(x/2):
        for j in range(y/2):
            k=max(raa[2*i][2*j],raa[2*i+1][2*j],raa[2*i][2*j+1],raa[2*i+1][2*j+1])
            rbb[i][j]=min(raa[i][j],k)
            rbb[i+x/2][j]=min(raa[i+x/2][j],k)
            rbb[i][j+y/2]=min(raa[i][j+y/2],k)
            rbb[i+x/2][j+y/2]=min(raa[i+x/2][j+y/2],k)

    for i in range(x/2):
        for j in range(y/2):
            k=max(gaa[2*i][2*j],gaa[2*i+1][2*j],gaa[2*i][2*j+1],gaa[2*i+1][2*j+1])
            gbb[i][j]=min(gaa[i][j],k)
            gbb[i+x/2][j]=min(gaa[i+x/2][j],k)
            gbb[i][j+y/2]=min(gaa[i][j+y/2],k)
            gbb[i+x/2][j+y/2]=min(gaa[i+x/2][j+y/2],k)
            
    for i in range(x/2):
        for j in range(y/2):
            k=max(baa[2*i][2*j],baa[2*i+1][2*j],baa[2*i][2*j+1],baa[2*i+1][2*j+1])
            bbb[i][j]=min(baa[i][j],k)
            bbb[i+x/2][j]=min(baa[i+x/2][j],k)
            bbb[i][j+y/2]=min(baa[i][j+y/2],k)
            bbb[i+x/2][j+y/2]=min(baa[i+x/2][j+y/2],k)

    raa=rbb
    gaa=gbb
    baa=bbb
    
    
    n=n+1
    print "n=",n
    
##printing out the final image##

for i in range(x):
    for j in range(y):
        img.setPixelF(i,j,(rbb[i][j],gbb[i][j],bbb[i][j],1))
        
        

print "done"



Hi,
what an original little script!
well done!
I hope you work on this some more.
An interface & some variables to set would be great.
I could see this become a handy little fractal image generator.

To use the script,
Copy the script to Blenders text editor. (then save it!)
Open an 512*512 image in the Image Editor.
Alt/P to run the script.
Great stuff.

That’s great. The script does a lot for a few lines of code. Good work.

interesting script. thank you for sharing!
the only request were the script could clip images to 2^x by 2^x (eg. 256256 or 512512) automatic.

Made a simple animation

How did you do the animation? From glancing over the script, it appears to just open a single image file, manipulate the data, and rewrite over the original image.

I wrote another script that opens a series of images and calls the fractalizer in turn on each of them. Once I’ve added a gui, I’ll upload another version with the ability to convert a sequence of pictures

now this is a cool script man, do you have a tutorial for making that sick animation =)

I can understand that the fractal algorithm may need input and output data to be in the form 2^n, but why not store and convert pixel data from arbitrarily sized images before passing to the algo? This way, you will probably get more people to use your script on whatever images they have.

Couldn’t resist the temptation to see if I could reduce the number of lines of code:


import copy
from Blender import Image

##Import the image##
img=Image.GetCurrent()
(x,y)=img.getSize()
print x,y

oi=[[img.getPixelF(i,j) for j in range(y)]for i in range(x)] # old image data
ni=copy.deepcopy(oi) # new image data

n=0

while 2**n<=x:
    for i in range(x/2):
        for j in range(y/2):
            for m in range(3):
                k=max(oi[2*i][2*j][m],oi[2*i+1][2*j][m],oi[2*i][2*j+1][m],oi[2*i+1][2*j+1][m])
                ni[i][j][m]=min(oi[i][j][m],k)
                ni[i+x/2][j][m]=min(oi[i+x/2][j][m],k)
                ni[i][j+y/2][m]=min(oi[i][j+y/2][m],k)
                ni[i+x/2][j+y/2][m]=min(oi[i+x/2][j+y/2][m],k)
    oi,ni=ni,oi
    n+=1
    print "n=%02d" %n

##printing out the final image##
for i in range(x):
    for j in range(y):img.setPixelF(i,j,ni[i][j])

print "done"


Still don’t under stand the math though.