Skip to content

Instantly share code, notes, and snippets.

@damp11113
Last active April 3, 2024 16:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damp11113/5ba2cf22b883bb748cc9b243666b1932 to your computer and use it in GitHub Desktop.
Save damp11113/5ba2cf22b883bb748cc9b243666b1932 to your computer and use it in GitHub Desktop.
camouflage generator using cellular automata algorithm
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")
@damp11113
Copy link
Author

Output:
0
2
7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment