Created
July 11, 2019 06:35
-
-
Save greysondn/0b77edb05369b6a4f47c8c74e2a35101 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Python 3.7.2rc1 in windows, using PILLOW and tqdm | |
# WTFPL, released by greysondn <greysondn.github.io> | |
# | |
# input images must be all the same size or this is likely to break | |
# may commit murder, arson, and jaywalking without warning. | |
from PIL import Image | |
from tqdm import tqdm, trange | |
import os | |
# class to hold configuration | |
# feel free to change/etc this for your case | |
class DespicableConfig(): | |
def __init__(self): | |
# path this is supposed to do | |
self.PATH = ".\src" | |
# size data expected | |
self.height = 750 | |
self.width = 1334 | |
# color value storage, quick and messy | |
class ColVal(): | |
def __init__(self): | |
# red, green, blue | |
self.r = 0.0 | |
self.g = 0.0 | |
self.b = 0.0 | |
# main function | |
def main(): | |
# init a conf handle | |
config = DespicableConfig() | |
# number of images we've worked on | |
imgCnt = 0 | |
# prevents one time code from repeating | |
firstImg = True | |
# values, in total, really just here for scope | |
values = [] | |
tqdm.write("Initing values array!") | |
for y in tqdm(range(config.height), "col"): | |
row = [] | |
for x in tqdm(range(config.width), "row"): | |
row.append(ColVal()) | |
values.append(row) | |
# so we pull open the images that should be at path, one by one... | |
for item in tqdm(os.listdir(config.PATH), "file"): | |
imgCnt = imgCnt + 1 | |
# if you gave it an invalid image, you're looking at this line puzzled. | |
im = Image.open(config.PATH + "/" + item) | |
# convert, remove alpha channel if it has one | |
im = im.convert(mode="RGB") | |
# get size | |
width, height = im.size | |
# check size, scale to match. | |
needsResized = False | |
if (width != config.width): | |
needsResized = True | |
if (height != config.height): | |
needsResized - True | |
if (needsResized): | |
im = im.resize((config.width, config.height)) # defaults to nearest neighbor, good enough for a meme. | |
# image guaranteed to be correct size now | |
# we can iterate over it | |
tqdm.write("Grabbing pixel data!") | |
for y in tqdm(range(config.height), "col"): | |
for x in tqdm(range(config.width), "row"): | |
# grab pixel, slam its data into the array for all images | |
# we know it's RGB because we converted it, makes life simple | |
pix = im.getpixel((x, y)) | |
values[y][x].r = values[y][x].r + pix[0] | |
values[y][x].g = values[y][x].g + pix[1] | |
values[y][x].b = values[y][x].b + pix[2] | |
# once we get here, the images have all been stepped through and it's just image count and the data | |
# create a new image, make it the average of the old one | |
outImg = Image.new("RGB", (config.width, config.height)) | |
tqdm.write("Generating output image!") | |
for y in tqdm(range(config.height), "col"): | |
for x in tqdm(range(config.width), "row"): | |
# this is horribly inefficient, but it will help me not get so lost | |
# I don't want to hear it, this is meant to be quick and dirty. | |
r = values[y][x].r | |
g = values[y][x].g | |
b = values[y][x].b | |
# to float | |
r = float(r) | |
g = float(g) | |
b = float(b) | |
# divide by number of images to get average values | |
r = r / (float(imgCnt)) | |
g = g / (float(imgCnt)) | |
b = b / (float(imgCnt)) | |
# round | |
r = round(r) | |
g = round(g) | |
b = round(b) | |
# to int | |
r = int(r) | |
g = int(g) | |
b = int(b) | |
# assign to pixel in out image | |
outImg.putpixel((x, y), (r, g, b)) | |
# save | |
outImg.save("out.png") | |
# main guard | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment