Skip to content

Instantly share code, notes, and snippets.

@damp11113
Created May 5, 2024 07:49
Show Gist options
  • Save damp11113/00bea1baba91f5c4cbb9b16c3d75a5f8 to your computer and use it in GitHub Desktop.
Save damp11113/00bea1baba91f5c4cbb9b16c3d75a5f8 to your computer and use it in GitHub Desktop.
camouflage generator using cellular automata algorithm v2. add smooth
import random
import numpy as np
from PIL import Image, ImageDraw, ImageFilter
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, blur=3, index=5):
self.grid_size = (grid_size, grid_size)
self.num_frames = num_frames
self.colors = color
self.ranseedx = ranseedx
self.ranseedy = ranseedy
self.blur = blur
self.index = index
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"
TL1 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[self.index]
thresed = TL1.point(lambda p: p > 128 and 255)
blured = thresed.filter(ImageFilter.GaussianBlur(self.blur))
L1 = blured.point(lambda p: p > 128 and 255)
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 2"
TL2 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[self.index]
thresed = TL2.point(lambda p: p > 128 and 255)
blured = thresed.filter(ImageFilter.GaussianBlur(self.blur))
L2 = blured.point(lambda p: p > 128 and 255)
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 3"
TL3 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[self.index]
thresed = TL3.point(lambda p: p > 128 and 255)
blured = thresed.filter(ImageFilter.GaussianBlur(self.blur))
L3 = blured.point(lambda p: p > 128 and 255)
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(512, index=20, num_frames=30)
outcamo = camo.gen()
outcamo.save(f"./camo/v2/{i}.png")
@damp11113
Copy link
Author

output
0

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