commit 93f32c5bac6cbebc9a741e8cc678328f228e0a21 Author: Leonora Tindall Date: Mon May 27 09:25:25 2024 -0500 Initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..92b2793 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.direnv diff --git a/gen.py b/gen.py new file mode 100644 index 0000000..34b9f98 --- /dev/null +++ b/gen.py @@ -0,0 +1,126 @@ +from PIL import Image, ImageFilter, ImageDraw, ImageEnhance +import random +import tempfile + +# Thickness of the bars in the third (test) row. +# No more than 10 +RESULTS = [0, 1, 4, 8, 16, 32, 20, 10, 5, 3] +# Travel of the bars in the third (test) row. +# No more than 10 +TRAVELS = [0, 0, 0, 3, 3, 3, 2, 1, 0, 4] + +SIZE = (1024, 256) +SSHIFT = 16 +OSIZE = (SIZE[0] + SSHIFT, SIZE[1] + SSHIFT) +NNOISEBLOT = random.randrange(128) + +im = Image.new("L", SIZE, "white") +draw = ImageDraw.Draw(im) + +# add large/macro noise +for _ in range(NNOISEBLOT): + noise_blot_x = random.randrange(OSIZE[0]) + noise_blot_y = random.randrange(OSIZE[1]) + noise_blot_size = random.randrange(int(max(OSIZE) / 32.0)) + draw.ellipse([(noise_blot_x, noise_blot_y), (noise_blot_x + noise_blot_size, + noise_blot_y + + noise_blot_size)], fill=226) + +# blur out macro noise +im = im.filter(ImageFilter.SMOOTH) +im = im.filter(ImageFilter.MedianFilter(size=3)) + +# flip one in four pixels to thwart sharpening +draw = ImageDraw.Draw(im) +for y in range(OSIZE[1]): + for x in range(OSIZE[0]): + if random.choice([True, False]): + npval = random.randrange(200, 250) + draw.point((x, y), fill=npval) + +# average, blur, and desaturate resulting noise to create backdrop +im = im.filter(ImageFilter.MedianFilter(size=3)) +im = im.filter(ImageFilter.GaussianBlur(radius=8)) + +BAR_X_MARGIN = OSIZE[0] / 32 +BAR_HEIGHT = OSIZE[1] / 16 +BAR_BOUNDING_LEN = (OSIZE[0] - BAR_X_MARGIN) / 16 +draw = ImageDraw.Draw(im) +for line_i in range(int((OSIZE[1] - BAR_HEIGHT) / (BAR_HEIGHT * 4))): + for bar_i in range(int((OSIZE[0] - BAR_X_MARGIN) / (BAR_BOUNDING_LEN + BAR_X_MARGIN))): + # for the p-control line, increasing concentration across + height = bar_i * 2 + + # for the n-control line, random very low positives + if line_i == 1: + height = random.randrange(0, 4) + if height < 3: + continue + height = height - 2 + + # for the test line, as indicated + if line_i == 2: + if len(RESULTS) > bar_i: + height = RESULTS[bar_i] + else: + height = 0 + if height == 0: + continue + + travel = 0 + if len(TRAVELS) > bar_i: + travel = TRAVELS[bar_i] + x_offset = random.randrange(int(BAR_BOUNDING_LEN / 3)) + y_offset = (BAR_HEIGHT - height) / 2 - random.randrange(int(BAR_HEIGHT / 4)) + start_x = (BAR_BOUNDING_LEN * bar_i) + (BAR_X_MARGIN * (bar_i + 1)) + x_offset + start_y = ((line_i + 1) * BAR_HEIGHT * 4) + y_offset - travel + draw.rectangle([start_x, start_y, start_x + BAR_BOUNDING_LEN, + start_y + height], fill=0) + + if height == 0: + continue + + opaq = random.randrange(0, 192) + incursion = random.randrange(1, 8) + draw.rectangle([start_x + incursion, start_y - 2, start_x + BAR_BOUNDING_LEN - incursion, + start_y + height - 2], fill=opaq) + draw.rectangle([start_x, start_y + (height/2) - 2, start_x + BAR_BOUNDING_LEN, + start_y + (height/2) + 2], fill=0) + + if len(TRAVELS) > bar_i and TRAVELS[bar_i] != 0: + start_x = (BAR_BOUNDING_LEN * bar_i) + (BAR_X_MARGIN * (bar_i + 1))\ + + x_offset + (BAR_BOUNDING_LEN * 0.10) + start_y = ((line_i + 1) * BAR_HEIGHT * 4) + y_offset + draw.rectangle([start_x, start_y, start_x + (BAR_BOUNDING_LEN * 0.80), + start_y + int(height / 2)], fill=64) + +im = im.filter(ImageFilter.MedianFilter(size=3)) + +# draw random bars of white for proceessing noise +draw = ImageDraw.Draw(im) +n_bars = random.randrange(1, 10) +for bar_i in range(int(n_bars)): + x = random.randrange(OSIZE[0]) + width = random.randrange(1, 3) + draw.line([x, 0, x + 3, OSIZE[1]], fill=255, width=width) + +n_bars = random.randrange(30, 300) +for pbar_i in range(int(n_bars)): + x = random.randrange(OSIZE[0]) + ys = random.randrange(OSIZE[1]) + l = random.randrange(int(OSIZE[1] / 3)) + draw.line([x, ys, x, ys + l], fill=255, width=1) + +n_bars = random.randrange(100, 1000) +for pbar_i in range(int(n_bars)): + y = random.randrange(OSIZE[1]) + xs = random.randrange(OSIZE[0]) + l = random.randrange(int(OSIZE[0] / 8)) + draw.line([xs, y, xs + l, y], fill=255, width=1) + +im = im.filter(ImageFilter.GaussianBlur(radius=3)) + +im = im.crop((SSHIFT/2, SSHIFT/2, SIZE[0] - SSHIFT/2, SIZE[1] - SSHIFT/2)) +f = tempfile.NamedTemporaryFile(suffix=".png", delete=False, delete_on_close=False) +im.save(f, format="png") +print(f.name) diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..c65f283 --- /dev/null +++ b/shell.nix @@ -0,0 +1,13 @@ +{ pkgs ? import (fetchTarball { + name = "nixos-24.05-2024-05-25"; + url = "https://github.com/nixos/nixpkgs/archive/d12251ef6e8e6a46e05689eeccd595bdbd3c9e60.tar.gz"; + sha256 = "0khxvys8iz32pffyqqlch4s6f28vk8wj20d8w29salh2pm35z3yi"; + }) {} }: + + pkgs.mkShellNoCC { + packages = with pkgs; [ + (python312.withPackages (ps: [ + ps.pillow + ])) + ]; + }