Skip to content

Instantly share code, notes, and snippets.

@greysondn
Created July 11, 2019 06:35
Show Gist options
  • Save greysondn/0b77edb05369b6a4f47c8c74e2a35101 to your computer and use it in GitHub Desktop.
Save greysondn/0b77edb05369b6a4f47c8c74e2a35101 to your computer and use it in GitHub Desktop.
# 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