aphid308
9/20/2014 - 3:23 PM

Python Datamosh GIF

A python script that takes a source image, processes it with glitch algorithms N times and stitches the images together into a GIF.

from PIL import Image
import subprocess
import os, sys
import string
import random

#Very early implementation
#This script will take an image file, glitch amount (the size of the text block to edit), offset (how far into the file to start), and frame count.
#It will then write a glitched file for each frame and output the animate gif.

baseimage = sys.argv[1]
glitchamount = int(sys.argv[2]) 
offset = int(sys.argv[3])
try:
    frames = int(sys.argv[4])
except IndexError:
    frames = 16

def filelen(infile):
    with open(infile) as f:
        for i, l in enumerate(f):
            pass
        return i + 1

def convertbmp(infile, outfile):
    outfile = outfile.split('.')[0] + '.bmp'
    image = Image.open(infile)

    try:
        if image.format != 'BMP':
            image.save(outfile, 'BMP')
            return outfile
        else:
            return outfile

    except IOError:
        return ("Cannot process", infile)

def glitchbmp(infile, outfile, amount, offset):
    outfile = outfile.split('.')[0] + '.bmp'
    lines = filelen(infile)
    print "%s is %i lines long. \n" % (infile, lines)
    minoffset = lines * 0.3
    maxoffset = lines - 50

    if offset < minoffset:
        offset = minoffset
        
        print "Offset is too low and may corrupt the header."
        print "Setting offset to minimum working value: %i" % minoffset

    elif offset > maxoffset:
        offset = maxoffset

        print "Offset is too high and may not create desired affect."
        print "Setting offset to maximum working value: %i" % maxoffset

    print "Substitution will start at %i \n" % offset
    end = offset + amount
    
    if end > lines:
        end = lines
    else:
        pass

    print "Substitution will end at %i \n" % end
    
    payload = ''.join(random.choice(string.hexdigits) for i in range(4))
    target = random.choice(string.hexdigits)
    sedcommand = "sed '%i,%i s/%s/%s/g' %s > %s" % (offset, end, target, payload, infile, outfile)
    
    print "String: '%s' will be replaced with '%s' \n" % (target, payload)
    print "Command to be run is: %s \n" % sedcommand

    subprocess.call(sedcommand, shell=True)

    return outfile

def animateglitch(infile, frames):

    convertedimage = convertbmp(baseimage, 'converted-%s' % baseimage)

    print "%s converted to %s \n" % (baseimage, convertedimage)

    i = frames

    while i > 0:
        glitchedimage = glitchbmp(convertedimage, 'glitched-' + baseimage.split('.')[0] + str(i) + '.bmp', glitchamount, offset)
        print "%s glitched to %s \n" % (convertedimage, glitchedimage)
        i -= 1

    animatecommand = "convert -delay 05 -loop 0 -quiet *bmp animated.gif"

    subprocess.call(animatecommand, shell=True)

animateglitch(baseimage, frames)