118 lines
3.8 KiB
Python
118 lines
3.8 KiB
Python
from random import random, choice
|
|
from PIL import Image, ImageFilter, ImageEnhance
|
|
from functools import reduce
|
|
|
|
import argparse
|
|
import os
|
|
import builtins
|
|
|
|
|
|
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)))
|
|
|
|
|
|
def clamp(min, value, max):
|
|
return builtins.max(min, builtins.min(value, max))
|
|
|
|
|
|
sepia = color_ramp((255 - int(random()*25), 230 + int(random()*25), 179+int(random()*25)))
|
|
|
|
|
|
class Mariusz:
|
|
def __init__(self, colors=sepia, decals=5, noise=.4, brightness=.9, blur=1.3):
|
|
self.colors = colors
|
|
self.decal_count = decals
|
|
self.noise = noise
|
|
self.brightness = brightness
|
|
self.blur = blur
|
|
|
|
self.decals = [os.path.join("decals", f) for f in os.listdir("decals") if os.path.isfile(os.path.join("decals", f))]
|
|
|
|
def fuck(self, image):
|
|
print("Fucking {}...".format(image))
|
|
im = Image.open(image)
|
|
im = im.convert("L")
|
|
im.putpalette(self.colors)
|
|
im = im.convert("RGBA")
|
|
im = ImageEnhance.Brightness(im).enhance(self.brightness)
|
|
|
|
ok = im.copy()
|
|
|
|
Mariusz.add_noise(im, self.noise)
|
|
for _ in range(self.decal_count):
|
|
Mariusz.add_decal(im, choice(self.decals))
|
|
|
|
im = im.filter(ImageFilter.GaussianBlur(self.blur))
|
|
damaged = im.convert("RGB")
|
|
|
|
return ok, damaged
|
|
|
|
@staticmethod
|
|
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)
|
|
|
|
@staticmethod
|
|
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")
|
|
parser.add_argument('-g', help='Blur level', type=float, default=1.5, dest="blur")
|
|
parser.add_argument('-b', help='Noise level', type=float, default=.9, dest="brightness")
|
|
|
|
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)
|
|
|
|
mariusz = Mariusz(sepia, args.decals, args.noise, args.brightness, args.blur)
|
|
if os.path.isfile(args.input):
|
|
ok, damaged = mariusz.fuck(args.input)
|
|
ok.convert('RGB').save(args.output)
|
|
damaged.convert('RGB').save(args.damaged)
|
|
else:
|
|
for f in os.listdir(args.input):
|
|
path = os.path.join(args.input, f)
|
|
|
|
ok, damaged = mariusz.fuck(os.path.join(args.input, f))
|
|
ok.convert('RGB').save(os.path.join(args.output, f))
|
|
damaged.convert('RGB').save(os.path.join(args.damaged, f))
|