NxN Pixalated GiF - Brett Paufler - Hardly Working
NxN Pixalated GiF - Brett Paufler - San Francisco Bay

NxN: Pixelated GiF Effect

A quick walk thru of a Python Numpy Digital Image Manipulation Effect.

Python Code

Should be commented adequately for those who care.
#for img import, export
from skimage.io import imread, imsave

#for quick img array manipulation
import numpy as np

#to convert array of img's to a gif
import moviepy.editor as mpy


def image_effect_nxn(image):
    '''quick output survey to find an effect worth pursuing
    image is the file location of an image
    '''
    
    #Load the image, get some feedback info
    img = imread(image, dtype=int)
    print image
    print img.shape
    print np.max(img)
    print img[0:5,0:5,0]
    
    #img^2, the effect sequence I settled on
    img = imread(image, dtype=int)
    img = img * img
    sN = image[:-4] + '_base' + image[-4:]
    imsave(sN, img)
    
    #img^3, next layer in the sequence
    img = imread(image, dtype=int)
    triple = img * img * img
    sN = image[:-4] + '_triple' + image[-4:]
    imsave(sN, triple)
    
    #img^4, using the power notation
    #which we'll use below in an incrementing for loop
    img = imread(image, dtype=int)
    quad = np.power(img,4)
    sN = image[:-4] + '_quad' + image[-4:]
    imsave(sN, quad)
    
    #mod 255 often gives a contour line effect
    #not utilized any further than this
    img = imread(image, dtype=int)
    modImg = np.mod(img,255)
    #modImg = np.mod(img*img,255) #sim to img*img
    sN = image[:-4] + '_mod' + image[-4:]
    imsave(sN, modImg)

    #img^2 yields values as high as 255*255
    #color only goes to 255
    #so this forces color range down
    #it added no value
    img = np.array(img, dtype=float)
    img = img/np.max(img)*255
    #img = img/np.max(img)*255 #sim to img*img
    img = np.array(img, dtype=int)
    sN = image[:-4] + '_normalized' + image[-4:]
    imsave(sN, img)
    
    #another unused attempt to modulate (reduce)
    #the effect of the power function
    img = imread(image, dtype=int)
    ten = img * img / 10
    sN = image[:-4] + '_ten' + image[-4:]
    imsave(sN, ten)

    #corresponding to the img printout at the start
    #this scrolled down as I added sub-routines above
    #providing feedback for each step
    print img.shape
    print np.max(img)
    print img[0:5,0:5,0]

image_effect_nxn(image)

Output in order of above.

Raw Image In
img = img

image_effect_nxn - Brett Paufler - Hardly Working - Raw Image
image_effect_nxn - Brett Paufler - San Francisco Bay - Raw Image


Base Effect
img*img

image_effect_nxn - Brett Paufler - Hardly Working - Base Effect
image_effect_nxn - Brett Paufler - San Francisco Bay - Base Effect


Triple
img*img*img

image_effect_nxn - Brett Paufler - Hardly Working - Triple Effect
image_effect_nxn - Brett Paufler - San Francisco Bay - Triple Effect


Quad Four
np.power(img,4)

image_effect_nxn - Brett Paufler - Hardly Working - Quad Effect
image_effect_nxn - Brett Paufler - San Francisco Bay - Quad Effect


Mod 255
np.mod(img,255)
(ultimately not used)

image_effect_nxn - Brett Paufler - Hardly Working - Mod Effect
image_effect_nxn - Brett Paufler - San Francisco Bay - Mod Effect


Normalized
img/np.max(img)*255
(hardly a compelling effect)

image_effect_nxn - Brett Paufler - Hardly Working - normalized Effect
image_effect_nxn - Brett Paufler - San Francisco Bay - normalized Effect


Ten
img * img / 10
(ultimately not used)

image_effect_nxn - Brett Paufler - Hardly Working - Ten Effect
image_effect_nxn - Brett Paufler - San Francisco Bay - Ten Effect


Pick a Horse & Run with It

I like the img*img effect. It's what I originally planned. It's what's at the top of the page. It's what got you here. So good enough.

def nxn(image):
    '''returns a pixelated gif and intermediate jpg images
    given an image location address in
    '''
    
    #loads the image
    img = imread(image, dtype=int)
    
    
    p = [] #array to save intermediate results
    #main loop in which increasingly pixelated (higher power)
    #image is saved to file and added to array p
    for n in range(2,6):
        pI = np.power(img,n)
        sN = image[:-4] + '_power_' + str(n) + image[-4:]
        imsave(sN, pI)
        p.append(pI)
    
    #uncomment if the end gif is desired to reverse at the end
    #(useful in many cases but not this one, IMO)
    #per above p contains [2,3,4,5] or locations 0,1,2,3
    #so adding locations 2,1 to end yields values [2,3,4,5,4,3]
    #for n in [2,1]:
    #    p.append(p[n])

    #save the gif using the moviepy editor library
    sN = image[:-4] + '_powerGIF.gif'
    clip = mpy.ImageSequenceClip(p, fps=5)
    clip.write_gif(sN)

nxn(image)

Output in increasing power order.

2
np.power(img,2)

image_effect_nxn - Brett Paufler - Hardly Working - Power 2
image_effect_nxn - Brett Paufler - San Francisco Bay - Power 2


3
np.power(img,3)

image_effect_nxn - Brett Paufler - Hardly Working - Power 3
image_effect_nxn - Brett Paufler - San Francisco Bay - Power 3


4
np.power(img,4)

image_effect_nxn - Brett Paufler - Hardly Working - Power 4
image_effect_nxn - Brett Paufler - San Francisco Bay - Power 4


5
np.power(img,5)

image_effect_nxn - Brett Paufler - Hardly Working - Power 5
image_effect_nxn - Brett Paufler - San Francisco Bay - Power 5


Which Brings Us Back to the Start
Power 2-5, GiF'd

image_effect_nxn - Brett Paufler - Hardly Working - Power 5
image_effect_nxn - Brett Paufler - San Francisco Bay - Power 5




Bonus Section
Root Test

Fractional Powers

np.power(img,1.0/2)

image_effect_nxn - Brett Paufler - Hardly Working - Root 2
image_effect_nxn - Brett Paufler - San Francisco Bay - Root 2


np.power(img,1.0/3)

image_effect_nxn - Brett Paufler - Hardly Working - Root 3
image_effect_nxn - Brett Paufler - San Francisco Bay - Root 3


np.power(img,1.0/4)

image_effect_nxn - Brett Paufler - Hardly Working - Root 4
image_effect_nxn - Brett Paufler - San Francisco Bay - Root 4


np.power(img,1.0/5)

image_effect_nxn - Brett Paufler - Hardly Working - Root 5
image_effect_nxn - Brett Paufler - San Francisco Bay - Root 5


np.power(img,1.0/6)

image_effect_nxn - Brett Paufler - Hardly Working - Root 6
image_effect_nxn - Brett Paufler - San Francisco Bay - Root 6


np.power(img,1.0/7)

image_effect_nxn - Brett Paufler - Hardly Working - Root 7
image_effect_nxn - Brett Paufler - San Francisco Bay - Root 7


Note: to save on bandwidth, the same display images are utilized when there was no visually noticeable difference in output (original = normalized, img*img = power 2, triple = power 3).


For more, please see
www.paufler.net



Brett@Paufler.net
Terms of Service
© Copyright 2015 Brett Paufler