diff --git a/classes/Collage.py b/classes/Collage.py index beceb9e..a208a44 100644 --- a/classes/Collage.py +++ b/classes/Collage.py @@ -1,6 +1,7 @@ from PIL import Image from bisect import bisect_left +# Create instructions for the Collage constructor class Schematic(): def __init__(self,template,samples): self.template = template @@ -9,10 +10,12 @@ class Schematic(): self.schematic = {} self.create_schematic() + # Use array bisection to find the closest matching sample by HEX color def query_sample(self,value): samples = [*self.samples] pos = bisect_left(samples,value) + # Reset on under- and overflows if(pos < 1 or pos > len(samples) - 1): pos = 0 @@ -26,9 +29,10 @@ class Schematic(): eyedropper = "%02x%02x%02x" % (r,g,b) self.schematic[x][y] = self.query_sample(eyedropper) - print(f"Generated schematic for pixel at index [{x},{y}] ",end="\r",flush="True") + print(f"Found best match for index [{x},{y}] ",end="\r",flush="True") print("") +# Construct collage by loading images defined in schematic class Collage(): def __init__(self,input_file,samples): self.template = Image.open(input_file) @@ -40,35 +44,41 @@ class Collage(): self.collage = self.create_canvas() self.create_collage() + # Create the upscaled output image def create_canvas(self): canvas_width = self.size[0] * self.template.size[0] canvas_height = self.size[1] * self.template.size[1] return Image.new("RGB",(canvas_width,canvas_height)) + # Assemble the collage def create_collage(self): schematic = Schematic(self.template,self.samples).schematic offset_x = 0 offset_y = 0 + # Apply each sample by raster scanning for x in range(1,self.template.size[0]): offset_x = 0 for y in range(1,self.template.size[1]): - key = schematic[x][y] - resolve_posix = self.samples[key] + key = schematic[x][y] # Get sample index for current pixel + resolve_posix = self.samples[key] # Convert sample index to sample set index + # Load and resize the requested sample from disk sample = Image.open(self.samples_posix[resolve_posix]) sample = sample.resize(self.size) + # Add the loaded sample to the collage self.collage = self.collage.copy() self.collage.paste(sample,(offset_x,offset_y)) offset_x += self.size[0] - print(f"Pasted best matched sample for index [{x},{y}] ",end="\r",flush="True") + print(f"Pasted sample at index [{x},{y}] ",end="\r",flush="True") offset_y += self.size[1] print("") + # Save collage to disk def put(self,dest): self.collage.save(dest,"JPEG") diff --git a/create.py b/create.py new file mode 100644 index 0000000..78a9d11 --- /dev/null +++ b/create.py @@ -0,0 +1,21 @@ +import sys +from classes.Samples import Samples +from classes.Collage import Collage +from pathlib import Path + +force = False # Will generate a new sample set every time when true + +# Prompt IO declaration if no CLI arguments provided +if(len(sys.argv) < 2): + input_file = input("Input image (.jpg):\n") + output_file = input("Output image (.jpg):\n") +else: + input_file = sys.argv[1] + output_file = sys.argv[2] + +# Load all images from the "samples/" folder +samples = Samples("samples",force) + +# Create a collage from the loaded samples +collage = Collage(input_file,samples) +collage.put(output_file) \ No newline at end of file diff --git a/main.py b/main.py deleted file mode 100644 index 8307af5..0000000 --- a/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from classes.Samples import Samples -from classes.Collage import Collage -from pathlib import Path - -force = False -input_path = "input/" - -# Load all JPGs from the "samples/" folder -samples = Samples("samples",force) - -input_file = str("input/coffee-resized.jpg") - -collage = Collage(input_file,samples) -collage.put(input_file + "_collage.jpg") - -# input_files = Path(input_path).glob("*.jpg") -# input_files_posix = [x for x in input_files if x.is_file()] # List of PosixPaths - -# for input_file in input_files_posix: -# input_file = str(input_file) -# collage = Collage(input_file,samples) -# collage.put(input_file + "_collage.jpg") \ No newline at end of file