Skip to content

Instantly share code, notes, and snippets.

@mattdennewitz
Created October 15, 2010 02:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mattdennewitz/627514 to your computer and use it in GitHub Desktop.
Save mattdennewitz/627514 to your computer and use it in GitHub Desktop.
python port of corrupt, for image disruption.
#!/usr/bin/env python
"""
corrupt
usage: ./corrupt.py --source=input.jpg [--output=corrupted.jpg] [--iterations=10]
originally: http://www.recyclism.com/corrupt.php
ported: @mattdennewitz
"""
import argparse
import os
from random import randint
from PIL import Image
DEFAULT_ITERATIONS = 10
DEFAULT_OUTPUT = "corrupt.jpg"
class InvalidImageException(Exception):
pass
def corrupt(source, output=DEFAULT_OUTPUT, iterations=DEFAULT_ITERATIONS):
"""Reconsider byte arrangement from ``input``, render to ``output.
@param source Path to source image
@param output Path to output image
@param iterations How many times to rethink and rearrange.
"""
def read_chunks(fh):
"Read a file in chunks. Useful for larger images."
while True:
chunk = fh.read(4096)
if not chunk:
break
yield chunk
try:
Image.open(source)
except:
raise InvalidImageException("%s appears to be broken." % source)
# read the image, copy into a buffer for manipulation
source_image = open(source, "r")
output_image = open(output, "w+b")
for chunk in read_chunks(source_image):
output_image.write(chunk)
source_image.close()
# herald the destroyer
iters = 0
steps = 0
block_start = 100
block_end = os.path.getsize(source) - 400
replacements = randint(1, 30)
while iters <= iterations:
while steps <= replacements:
pos_a = randint(block_start, block_end)
pos_b = randint(block_start, block_end)
output_image.seek(pos_a)
content_from_pos_a = output_image.read(1)
output_image.seek(0)
output_image.seek(pos_b)
content_from_pos_b = output_image.read(1)
output_image.seek(0)
# overwrite A with B
output_image.seek(pos_a)
output_image.write(content_from_pos_b)
output_image.seek(0)
# overwrite B with A
output_image.seek(pos_b)
output_image.write(content_from_pos_a)
output_image.seek(0)
steps += 1
iters += 1
output_image.close()
if __name__ == "__main__":
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("--source", help="Path to source image",
dest="source", required=True)
arg_parser.add_argument("--output", help="Path to glitched mayhem output",
dest="output", required=False,
default="glitched.jpg")
arg_parser.add_argument("--iterations", type=int, help="# Iterations",
default=DEFAULT_ITERATIONS, dest="iterations")
app_args = arg_parser.parse_args()
corrupt(app_args.source, output=app_args.output,
iterations=app_args.iterations)
@mattdennewitz
Copy link
Author

makes no attempt to verify that the output is a valid jpeg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment