from random import random, choice from PIL import Image, ImageFilter from functools import reduce import argparse import os def color_ramp(white=(255, 255, 255), black=(0, 0, 0)): wr, wg, wb = white br, bg, bb = black colors = [[br + (wr - br) * i / 255, bg + (wg - bg) * i / 255, bb + (wb - bb) * i / 255] for i in range(255)] return list(map(int, reduce(list.__add__, colors))) sepia = color_ramp((255 - int(random()*25), 230 + int(random()*25), 179+int(random()*25))) decals = [os.path.join("decals", f) for f in os.listdir("decals") if os.path.isfile(os.path.join("decals", f))] def clamp(x, value, y): return max(x, min(value, y)) def add_decal(image, decal): decal = Image.open(decal) w, h = image.size scale = .5 + random() scale = scale * min(w/decal.size[0], 1) decal = decal.rotate(random() * 360, expand=True) decal = decal.resize(map(int, (scale * decal.size[0], scale * decal.size[1])), Image.ANTIALIAS) dw, dh = decal.size pos = tuple(map(int, (random() * w - .5 * dw, random() * h - .5 * dh))) image.paste(decal, pos, decal) def add_noise(image, level): data = image.getdata() def noise(t): w = int(random() * 255 * level) r, g, b, a = t return clamp(0, r - w, 255), clamp(0, g - w, 255), clamp(0, b - w, 255), a data = list(map(noise, data)) image.putdata(data) if __name__ == '__main__': parser = argparse.ArgumentParser(description="Damages image") parser.add_argument('input', help='Image to damage', type=str) parser.add_argument('output', help='Output image name', type=str, nargs='?') parser.add_argument('damaged', help='Output damaged image name', type=str, nargs='?') parser.add_argument('-d', help='Decals count', type=int, default=8, dest="decals") parser.add_argument('-n', help='Noise level', type=float, default=.4, dest="noise") args = parser.parse_args() if args.output is None: dir, name = os.path.split(args.input) args.output = os.path.join(dir, "ok_" + name) if args.damaged is None: dir, name = os.path.split(args.input) args.damaged = os.path.join(dir, "damaged_" + name) im = Image.open(args.input) im = im.convert("L") im.putpalette(sepia) im = im.convert("RGBA") im.convert("RGB").save(args.output) add_noise(im, args.noise) for _ in range(args.decals): add_decal(im, choice(decals)) im = im.filter(ImageFilter.GaussianBlur(1.5)) im.convert("RGB").save(args.damaged)