Last active
April 3, 2024 16:57
-
-
Save damp11113/5ba2cf22b883bb748cc9b243666b1932 to your computer and use it in GitHub Desktop.
camouflage generator using cellular automata algorithm
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
import random | |
import numpy as np | |
from PIL import Image, ImageDraw | |
from damp11113.processbar import indeterminateStatus | |
class camogen: | |
def __init__(self, grid_size=128, num_frames=15, color=[(75, 83, 32), (225, 215, 152), (103, 86, 69), (66, 71, 86)], ranseedx=0, ranseedy=100): | |
self.grid_size = (grid_size, grid_size) | |
self.num_frames = num_frames | |
self.colors = color | |
self.ranseedx = ranseedx | |
self.ranseedy = ranseedy | |
def initialize_grid(self, seed=None): | |
if seed is not None: | |
np.random.seed(seed) | |
return np.random.choice([0, 1], size=self.grid_size) | |
def apply_rules(self, grid): | |
neighbor_count = sum(np.roll(np.roll(grid, i, 0), j, 1) for i in (-1, 0, 1) for j in (-1, 0, 1) if (i != 0 or j != 0)) | |
return (neighbor_count == 3) | (grid & (neighbor_count == 2)) | |
def update_grid(self, grid): | |
new_grid = self.apply_rules(grid) | |
grid[:] = new_grid[:] | |
return grid | |
def generate_frames(self, grid): | |
images = [] | |
for idx in range(self.num_frames): | |
img = Image.new('RGBA', self.grid_size) | |
draw = ImageDraw.Draw(img) | |
for i in range(self.grid_size[0]): | |
for j in range(self.grid_size[1]): | |
if grid[i, j] == 1: | |
draw.rectangle([j, i, j + 1, i + 1], fill='black') | |
img = img.convert("RGBA") | |
datas = img.getdata() | |
newData = [] | |
for item in datas: | |
if item[0] in range(200, 256) and item[1] in range(200, 256) and item[2] in range(200, 256): | |
newData.append((255, 255, 255, 0)) | |
else: | |
newData.append(item) | |
img.putdata(newData) | |
images.append(img) | |
grid = self.update_grid(grid) | |
return images | |
def gen(self): | |
loading = indeterminateStatus(desc=f"generating camo {self.grid_size[0]}x{self.grid_size[1]}", end="[ ✔ ] generated") | |
loading.start() | |
# Randomly choose a new position for each color | |
new_positions = list(range(len(self.colors))) | |
random.shuffle(new_positions) | |
# Create a new list with colors shuffled to new positions | |
colors = [self.colors[i] for i in new_positions] | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 0" | |
L0 = Image.new("RGBA", self.grid_size) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 1" | |
L1 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[10] | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 2" | |
L2 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[10] | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 3" | |
L3 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[10] | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 0" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B = colors[0] | |
L0.putpixel((x, y), (R, G, B, 255)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 1" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B, A = L1.getpixel((x, y)) | |
if A == 255: | |
R, G, B = colors[1] | |
L1.putpixel((x, y), (R, G, B, A)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 2" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B, A = L2.getpixel((x, y)) | |
if A == 255: | |
R, G, B = colors[2] | |
L2.putpixel((x, y), (R, G, B, A)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 3" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B, A = L3.getpixel((x, y)) | |
if A == 255: | |
R, G, B = colors[3] | |
L3.putpixel((x, y), (R, G, B, A)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} mixing" | |
merged_image = Image.alpha_composite(L0, L1) | |
merged_image = Image.alpha_composite(merged_image, L2) | |
merged_image = Image.alpha_composite(merged_image, L3) | |
loading.stop() | |
return merged_image | |
for i in range(10): | |
camo = camogen(128) | |
outcamo = camo.gen() | |
outcamo.save(f"./camo/{i}.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output:


